简体   繁体   中英

Extract unsigned values from certain bits in C# ushort

I need a good way of extracting values from certain bits inside a unsigned short:

The definition of the 4 alarms inside the ushort:

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

The value of the ushort: 4383 or (1000100011111 in binary)

So what i want to achieve is:

1001100110011001
Alarm1.....Alarm2.....Alarm3......Alarm4
1001.......1001.......1001........1001

Gets translated into:
Alarm1....Alarm2....Alarm3....Alarm4
9............9............9............9

Using the pseudo code:

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);

Regards, Johan

int GetFromBits(ushort bits, int offset)
{
 return (bits >> (offset - 1)) & 0xF;
}
bool GetBit(ushort bits, int offset) {
    return (bits & (1<<offset)) != 0;
}

Unless there's a particular reason to use a ushort, I'd highly recommend you use enum flags . That was the intended replacement for bitwise operations in C#.

Use enums:

[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);

A VB example using enum flags

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM