2010-11-18 23 views
0

Ich brauche eine gute Möglichkeit der Werte von bestimmten Bits in einem unsigned short Extraktion:Extract unsigned Werte von bestimmten Bits in C# ushort

Die Definition der 4 Alarme innerhalb des 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 Wert des ushort: 4383 oder (1000100011111 in binär)

Also, was ich erreichen will ist:

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

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

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

Grüße, Johan

Antwort

4
int GetFromBits(ushort bits, int offset) 
{ 
return (bits >> (offset - 1)) & 0xF; 
} 
+0

Vielen Dank! Dies funktioniert perfekt für einen Fall, in dem alle 16 Bits belegt sind. Getestet, und es funktioniert, ich konnte alle Werte extrahieren. –

2
bool GetBit(ushort bits, int offset) { 
    return (bits & (1<<offset)) != 0; 
} 
+0

Ja, das nur das einzelne Bit extrahiert. Ich extrahiere die 4 angegebenen Bits und dann den Wert, der maximal 15 ist –

+0

Ja, ich verstehe. Yossarian hat die richtige Lösung gepostet. –

0

Es sei denn, ein Grund gibt es insbesondere eine ushort zu verwenden, würde ich sehr empfehlen Sie enum flags verwenden. Das war der beabsichtigte Ersatz für bitweise Operationen in C#.

0

Verwendung Aufzählungen:

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

Ich interpretiere Daten, die von Hardware gelesen werden, ich hatte gehofft, dass jedes Bit etwas bedeutet, aber in diesem Fall kann jeder Alarm 1 bis 15 verschiedene Zustände haben, was die Dinge komplizierter macht. –

0

Ein VB Beispiel unter Verwendung von 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 
+0

Ich sehe, jemand entwickelt auch Software für Dieselaggregate !!! Ich habe einen effizienteren Weg gefunden, diese Alarme zu verwalten, sie sind ziemlich schwierig, weil jeder von ihnen 15 verschiedene Zustände hat. –

+0

@Johan - Nein, ich bin nicht, nur eine glückliche Vermutung. Was ich zu zeigen versuchte, waren zwei verschiedene Möglichkeiten. Ich habe gezeigt, wie jeder Vier-Bit-Wert separat und als Wert mit Enums behandelt wird. – dbasnett