从C#ushort中的某些位提取无符号值
我需要一种从无符号short中的某些位提取值的好方法: ushort内4个报警的定义:从C#ushort中的某些位提取无符号值,c#,extract,bit-manipulation,bits,C#,Extract,Bit Manipulation,Bits,我需要一种从无符号short中的某些位提取值的好方法: ushort内4个报警的定义: Name......Range.......Bits Alarm4....0-15....13/16-16/16 Alarm3....0-15....9/16-12/16 Alarm2....0-15....5/16-8/16 Alarm1....0-15....1/16-4/16 ushort的值:4383或(二进制中的100011111) 因此,我想要实现的是: 1001100110011001 Ala
Name......Range.......Bits
Alarm4....0-15....13/16-16/16
Alarm3....0-15....9/16-12/16
Alarm2....0-15....5/16-8/16
Alarm1....0-15....1/16-4/16
ushort的值:4383或(二进制中的100011111)
因此,我想要实现的是:
1001100110011001
Alarm1.....Alarm2.....Alarm3......Alarm4
1001.......1001.......1001........1001
Gets translated into:
Alarm1....Alarm2....Alarm3....Alarm4
9............9............9............9
使用伪代码:
getValueFunc(ushort bits, int offset);
ushort u = 4383;
UInt16 Alarm1Value = getValueFunc(u, 1);
UInt16 Alarm2Value = getValueFunc(u, 5);
UInt16 Alarm3Value = getValueFunc(u, 9);
UInt16 Alarm4Value = getValueFunc(u, 13);
问候,,
Johanbool GetBit(ushort位,int偏移量){
返回(位和(1bool GetBit)(ushort位,int偏移量){
return(bits&(1除非有特殊原因使用ushort,否则我强烈建议您使用
.这是C#中按位操作的预期替代品。除非有特殊原因使用ushort,否则我强烈建议您使用
.这是C#中按位操作的预期替代品。使用枚举:
[Flags]
public enum Alarm : int
{
AlarmValue1 = 0x1,
AlarmValue2 = // the Hex Value,
AlarmValue3 = // the Hex Value,
AlarmValue4 = // the Hex Value
}
ushort myValue = 0x687;
Alarm alarm = (Alarm) myValue;
Console.WriteLine(alarm & AlarmValue3);
使用枚举:
[Flags]
public enum Alarm : int
{
AlarmValue1 = 0x1,
AlarmValue2 = // the Hex Value,
AlarmValue3 = // the Hex Value,
AlarmValue4 = // the Hex Value
}
ushort myValue = 0x687;
Alarm alarm = (Alarm) myValue;
Console.WriteLine(alarm & AlarmValue3);
使用枚举标志的VB示例
Public Class Form1
<FlagsAttribute()> _
Public Enum Alarms As UShort
'bits in short
'1 1 1 1 1 1
'5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
No_Alarms = 0 'do not change
Alarm1All = &HF
HighTemp1 = 1 << 0
LowOilPress1 = 1 << 1
HighRPM1 = 1 << 2
LowRPM1 = 1 << 3
Alarm2All = &HF0 'alarm two is a 4 bit value 0 - 15
_bit0AL2 = 1 << 4
_bit1AL2 = 1 << 5
_bit2AL2 = 1 << 6
_bit3AL2 = 1 << 7
Alarm3All = &HF00
Cond3_0 = 1 << 8
Cond3_1 = 1 << 9
Cond3_2 = 1 << 10
Cond3_3 = 1 << 11
Alarm4All = &HF000
DoorAjar = 1 << 12
O2Sensor = 1 << 13
LightsOn = 1 << 14
LowFuel = 1 << 15
All_Alarms = &HFFFF 'do not change
zAlarm1Offs = 0US
zAlarm2Offs = 4US
zAlarm3Offs = 8US
zAlarm4Offs = 12US
End Enum
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim foo As Alarms = Alarms.No_Alarms 'set no alarms
debugAlarm(foo)
'turn some alarms on
foo = Alarms.HighTemp1 Or Alarms.LowOilPress1
debugAlarm(foo)
'turn some more on
foo = foo Or Alarms._bit0AL2 Or Alarms._bit3AL2 Or Alarms.Cond3_2 Or Alarms.Cond3_3 Or Alarms.LightsOn Or Alarms.LowFuel
debugAlarm(foo)
'check Alarm4
If (foo And Alarms.Alarm4All) <> Alarms.No_Alarms Then 'any fours on
'check which 4
If (foo And Alarms.DoorAjar) = Alarms.DoorAjar Then
'Cond4_0 on
Stop
ElseIf (foo And Alarms.O2Sensor) = Alarms.O2Sensor Then
'Cond4_1 on
Stop
ElseIf (foo And Alarms.LightsOn) = Alarms.LightsOn Then
'Cond4_2 on
foo = foo And (Alarms.All_Alarms Xor Alarms.LightsOn) 'turn off Cond4_2
ElseIf (foo And Alarms.LowFuel) = Alarms.LowFuel Then
'Cond4_3 on
Stop
End If
End If
debugAlarm(foo)
'check Alarm2
If (foo And Alarms.Alarm2All) <> Alarms.No_Alarms Then 'any twos on
'check Alarm2 for values
Select Case CUShort(foo And Alarms.Alarm2All) 'foo And Alarms.Alarm2All
Case 1US << Alarms.zAlarm2Offs 'Alarms._bit0AL2
Stop
Case 2US << Alarms.zAlarm2Offs 'Alarms._bit1AL2
Stop
Case 3US << Alarms.zAlarm2Offs 'Alarms._bit0AL2 or Alarms._bit2AL2
Stop
Case 4US << Alarms.zAlarm2Offs
Stop
Case 5US << Alarms.zAlarm2Offs
Stop
Case 6US << Alarms.zAlarm2Offs
Stop
Case 7US << Alarms.zAlarm2Offs
Stop
Case 8US << Alarms.zAlarm2Offs
Stop
Case 9US << Alarms.zAlarm2Offs
debugAlarm(foo And Alarms.Alarm2All)
Stop
Case 10US << Alarms.zAlarm2Offs
Stop
Case 11US << Alarms.zAlarm2Offs
Stop
Case 12US << Alarms.zAlarm2Offs
Stop
Case 13US << Alarms.zAlarm2Offs
Stop
Case 14US << Alarms.zAlarm2Offs
Stop
Case 15US << Alarms.zAlarm2Offs
Stop
End Select
End If
debugAlarm(foo)
End Sub
Private Sub debugAlarm(ByVal _alarm As Alarms)
Debug.WriteLine("")
Dim asUshort As UShort = _alarm
Debug.WriteLine(_alarm.ToString)
Debug.WriteLine(Convert.ToString(asUshort, 2).PadLeft(16, "0"c))
End Sub
End Class
公共类表单1
_
公共枚举报警作为UShort
简言之
'1 1 1 1 1 1
'5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
无报警=0'不更改
Alarm1All=&HF
HighTemp1=1使用枚举标志的VB示例
Public Class Form1
<FlagsAttribute()> _
Public Enum Alarms As UShort
'bits in short
'1 1 1 1 1 1
'5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
No_Alarms = 0 'do not change
Alarm1All = &HF
HighTemp1 = 1 << 0
LowOilPress1 = 1 << 1
HighRPM1 = 1 << 2
LowRPM1 = 1 << 3
Alarm2All = &HF0 'alarm two is a 4 bit value 0 - 15
_bit0AL2 = 1 << 4
_bit1AL2 = 1 << 5
_bit2AL2 = 1 << 6
_bit3AL2 = 1 << 7
Alarm3All = &HF00
Cond3_0 = 1 << 8
Cond3_1 = 1 << 9
Cond3_2 = 1 << 10
Cond3_3 = 1 << 11
Alarm4All = &HF000
DoorAjar = 1 << 12
O2Sensor = 1 << 13
LightsOn = 1 << 14
LowFuel = 1 << 15
All_Alarms = &HFFFF 'do not change
zAlarm1Offs = 0US
zAlarm2Offs = 4US
zAlarm3Offs = 8US
zAlarm4Offs = 12US
End Enum
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim foo As Alarms = Alarms.No_Alarms 'set no alarms
debugAlarm(foo)
'turn some alarms on
foo = Alarms.HighTemp1 Or Alarms.LowOilPress1
debugAlarm(foo)
'turn some more on
foo = foo Or Alarms._bit0AL2 Or Alarms._bit3AL2 Or Alarms.Cond3_2 Or Alarms.Cond3_3 Or Alarms.LightsOn Or Alarms.LowFuel
debugAlarm(foo)
'check Alarm4
If (foo And Alarms.Alarm4All) <> Alarms.No_Alarms Then 'any fours on
'check which 4
If (foo And Alarms.DoorAjar) = Alarms.DoorAjar Then
'Cond4_0 on
Stop
ElseIf (foo And Alarms.O2Sensor) = Alarms.O2Sensor Then
'Cond4_1 on
Stop
ElseIf (foo And Alarms.LightsOn) = Alarms.LightsOn Then
'Cond4_2 on
foo = foo And (Alarms.All_Alarms Xor Alarms.LightsOn) 'turn off Cond4_2
ElseIf (foo And Alarms.LowFuel) = Alarms.LowFuel Then
'Cond4_3 on
Stop
End If
End If
debugAlarm(foo)
'check Alarm2
If (foo And Alarms.Alarm2All) <> Alarms.No_Alarms Then 'any twos on
'check Alarm2 for values
Select Case CUShort(foo And Alarms.Alarm2All) 'foo And Alarms.Alarm2All
Case 1US << Alarms.zAlarm2Offs 'Alarms._bit0AL2
Stop
Case 2US << Alarms.zAlarm2Offs 'Alarms._bit1AL2
Stop
Case 3US << Alarms.zAlarm2Offs 'Alarms._bit0AL2 or Alarms._bit2AL2
Stop
Case 4US << Alarms.zAlarm2Offs
Stop
Case 5US << Alarms.zAlarm2Offs
Stop
Case 6US << Alarms.zAlarm2Offs
Stop
Case 7US << Alarms.zAlarm2Offs
Stop
Case 8US << Alarms.zAlarm2Offs
Stop
Case 9US << Alarms.zAlarm2Offs
debugAlarm(foo And Alarms.Alarm2All)
Stop
Case 10US << Alarms.zAlarm2Offs
Stop
Case 11US << Alarms.zAlarm2Offs
Stop
Case 12US << Alarms.zAlarm2Offs
Stop
Case 13US << Alarms.zAlarm2Offs
Stop
Case 14US << Alarms.zAlarm2Offs
Stop
Case 15US << Alarms.zAlarm2Offs
Stop
End Select
End If
debugAlarm(foo)
End Sub
Private Sub debugAlarm(ByVal _alarm As Alarms)
Debug.WriteLine("")
Dim asUshort As UShort = _alarm
Debug.WriteLine(_alarm.ToString)
Debug.WriteLine(Convert.ToString(asUshort, 2).PadLeft(16, "0"c))
End Sub
End Class
公共类表单1
_
公共枚举报警作为UShort
简言之
'1 1 1 1 1 1
'5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
无报警=0'不更改
Alarm1All=&HF
HighTemp1=1是,仅提取单个位。我要提取4个指定位,然后获取值,最大值为15是,仅提取单个位。我要提取4个指定位,然后获取值,最大值为15非常感谢!这非常适合填充所有16位的情况。测试了它,我t工作,我能够提取所有值。非常感谢!这非常适合填充所有16位的情况。经过测试,它工作,我能够提取所有值。我正在解释从硬件读取的数据,我希望每个位都有意义,但在这种情况下,每个警报可以有1到15个不同的值状态,这使事情变得更复杂。我正在解释从硬件读取的数据,我希望每一位都有意义,但在这种情况下,每个警报可以有1到15个不同的状态,这使事情变得更复杂。我看到有人也在为柴油发电机组开发软件!!!我找到了一种更有效的管理方法这些警报非常棘手,因为每个警报都有15种不同的状态。@Johan-不,我不是,只是一个幸运的猜测。我想展示的是两种不同的可能性。我展示了如何分别对待每个四位值,并使用枚举作为一个值。我看到有人也在为柴油发电机组开发软件!!!我发现了一个更有效的方法管理这些警报的一种有效方法是,它们非常棘手,因为每一个警报都有15种不同的状态。@Johan-不,我不是,只是一个幸运的猜测。我试图展示的是两种不同的可能性。我展示了如何分别处理每个四位值,以及如何使用枚举作为一个值。