2010-11-18 45 views
0

je besoin d'une bonne façon d'extraire les valeurs de certains bits dans un court non signé:Extrait des valeurs non signées de certains bits en C# ushort

La définition des 4 alarmes à l'intérieur du 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 

Le valeur du ushort: 4383 ou (1.000.100.011.111 en binaire)

donc ce que je veux réaliser est:

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

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

En utilisant le code pseudo:

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

Cordialement, Johan

Répondre

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

Merci beaucoup! Cela fonctionne parfaitement pour un cas où tous les 16 bits sont peuplés. Testé, et cela fonctionne, j'ai été en mesure d'extraire toutes les valeurs. –

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

Oui, qui extrait seulement le seul bit. I extrac les 4 bits spécifiés, puis obtenir la valeur, qui est maximale 15 –

+0

Oui, je vois. Yossarian a posté la bonne solution. –

0

moins qu'il y ait une raison particulière d'utiliser un ushort, je recommande vivement d'utiliser enum flags. C'était le remplacement prévu pour les opérations au niveau du bit en C#.

0

Utilisez énumérations:

[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

J'interprète les données lues depuis le matériel, j'espérais que chaque bit signifiait quelque chose, mais dans ce cas chaque alarme peut avoir 1 à 15 états différents, ce qui complique les choses. –

0

exemple VB A l'aide de drapeaux enum

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

Je vois quelqu'un développe également un logiciel pour les groupes électrogènes diesel !!! J'ai trouvé un moyen plus efficace de gérer ces alarmes, elles sont assez délicates car chacune d'elles a 15 états différents. –

+0

@Johan - Non, je ne suis pas, juste une chance. Ce que j'essayais de montrer était deux possibilités différentes. J'ai montré comment traiter chaque valeur de quatre bits séparément et en tant que valeur en utilisant Enums. – dbasnett