我需要一种从unsigned 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或(二进制1000100011111)
所以我想要实现的是:
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);
此致 约翰
答案 0 :(得分:4)
int GetFromBits(ushort bits, int offset)
{
return (bits >> (offset - 1)) & 0xF;
}
答案 1 :(得分:2)
bool GetBit(ushort bits, int offset) {
return (bits & (1<<offset)) != 0;
}
答案 2 :(得分:0)
除非有特殊原因要使用ushort,否则我强烈建议您使用 enum flags。这是C#中按位运算的预期替代品。
答案 3 :(得分:0)
使用枚举:
[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);
答案 4 :(得分:0)
使用枚举标志的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