2009-09-17 16 views

Odpowiedz

15

To tak samo jak w C/C++:

// get the high order 16 bits 
int high = 0x12345678 >> 16; // high = 0x1234 
// set the high order 16 bits 
high = (high & 0x0000FFFF) + (0x5678 << 16); // high = 0x56781234 

EDIT: Bo jestem w dobrym nastroju, tutaj jesteś. Pamiętaj, że niezmienne typy są niezmienne! Funkcje "set" muszą być przypisane do czegoś.

public static class ExtensionMethods 
{ 
    public int LowWord(this int number) 
    { return number & 0x0000FFFF; } 
    public int LowWord(this int number, int newValue) 
    { return (number & 0xFFFF0000) + (newValue & 0x0000FFFF); } 
    public int HighWord(this int number) 
    { return number & 0xFFFF0000; } 
    public int HighWord(this int number, int newValue) 
    { return (number & 0x0000FFFF) + (newValue << 16); } 
} 

EDIT 2: Na drugim myśli, jeśli naprawdę trzeba to zrobić i nie chcą składnię wszędzie użyciu rozwiązanie Michaela. +1 do niego za pokazanie mi czegoś nowego.

+0

Dzięki, szybko! –

+0

Jeśli bardzo ich potrzebujesz i jeśli nostalgicznie spędzasz C dni, możesz stworzyć dla nich statyczne metody zwane LoWord(), HiWord(), LoByte() i HiByte(). Jestem zaskoczony, że te ekwiwalenty makroprocesorów nie były w jakiś sposób częścią jakiejś klasy .NET, takiej jak Int. – mjv

+0

Wykorzystuje to moc obliczeniową, która jest marnotrawstwem. W czasie kompilacji pożądany wzorzec bitowy jest już gdzieś na stosie i możemy dokładnie określić kompilatorowi, gdzie znajduje się ten wzorzec bitowy, aby można go było kopiować bez żadnych obliczeń. W tym celu użyj System.BitConverter. –

23

zestaw:

MessageBox.Show(string.Format("{0:X}", 8 | 0x12340000)); 

get:

MessageBox.Show(string.Format("{0:X}", 0xDEADBEEF >> 16)); 

[EDIT]

C# ma doskonałe wsparcie dla zmiennych dzielących ten sam obszar pamięci i bitów strukturyzacji

źródło: http://msdn.microsoft.com/en-us/library/acxa5b99(VS.80).aspx

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 


using System.Runtime.InteropServices; 

namespace Bitwise 
{ 
    public partial class Form1 : Form 
    { 

     [StructLayout(LayoutKind.Explicit)] 
     struct TestUnion 
     { 

      [FieldOffset(0)] 
      public uint Number; 

      [FieldOffset(0)] 
      public ushort Low; 

      [FieldOffset(2)] 
      public ushort High; 
     } 

     public Form1() 
     { 
      InitializeComponent();  

      var x = new TestUnion { Number = 0xDEADBEEF };   
      MessageBox.Show(string.Format("{0:X} {1:X} {2:X}", x.Number, x.High, x.Low)); 

      x.High = 0x1234;     
      MessageBox.Show(string.Format("{0:X} {1:X} {2:X}", x.Number, x.High, x.Low)); 

      x.Low = 0x5678; 
      MessageBox.Show(string.Format("{0:X} {1:X} {2:X}", x.Number, x.High, 

     } 
    } 
} 

UWAGA: od C# nie ma makro funkcji, powyższe podejście jest bardziej wydajnych niż przechodzącą zmiennej do metody/metod rozszerzenie

+6

+1 za DEADBEEF –

+1

+1 za pokazanie mi czegoś nowego. Teraz mam coś nowego do nadużywania. –

3

Chyba nie chcesz obliczeń kiedy chcesz Hiword/Hibyte lub LoWord/Lobyte, , jeśli System.Int32 zaczyna się od adresu 100 (więc zajmuje adres 100 do 103), chcesz jako LoWord dwa bajty zaczynające się od adresu 100 i 101, a Hiword to adres 102 i 103

Można to osiągnąć za pomocą klasy BitConverter. Ta klasa nie robi nic z bitami, używa tylko adresów do zwracania żądanej wartości.

Ponieważ rozmiar typów takich jak int/long jest różny dla każdej platformy, a WORD i DWORD są nieco mylące, używam systemów typu System.Int16/Int32/Int64. Nikt nigdy nie będzie miał problemów z odgadywaniem liczby bitów w System.Int32.

Za pomocą BitConvertera można przekonwertować dowolną liczbę całkowitą na tablicę bajtów rozpoczynającą się w tej lokalizacji i przekonwertować tablicę bajtów o odpowiedniej długości na odpowiednią liczbę całkowitą. Brak obliczenia potrzebne i nie ma bitów zmieni,

Załóżmy, że masz System.Int32 X (co jest DWORD w starych warunkach)

LOWORD: System.Int16 y = BitConverter.ToInt16(BitConverter.GetBytes(x), 0); 
HIWORD: System.Int16 y = BitConverter.ToInt16(BitConverter.GetBytes(x), 2); 

Dobrą rzeczą jest to, że działa na wszystkich długościach, ty don Aby uzyskać trzeci bajt, trzeba połączyć funkcje takie jak LOBYTE i HIORD:

HIByte(Hiword(x)) will be like: BitConverter.GetBytes(x)[3] 
0

Używam tych 2 funkcji ...

public static int GetHighint(long intValue) 
    { 
     return Convert.ToInt32(intValue >> 32); 
    } 

    public static int GetLowint(long intValue) 
    { 
     long tmp = intValue << 32; 
     return Convert.ToInt32(tmp >> 32); 
    } 
1

inny alternatywny

public class Macro 
    { 
     public static short MAKEWORD(byte a, byte b) 
     { 
      return ((short)(((byte)(a & 0xff)) | ((short)((byte)(b & 0xff))) << 8)); 
     } 

     public static byte LOBYTE(short a) 
     { 
      return ((byte)(a & 0xff)); 
     } 

     public static byte HIBYTE(short a) 
     { 
      return ((byte)(a >> 8)); 
     } 

     public static int MAKELONG(short a, short b) 
     { 
      return (((int)(a & 0xffff)) | (((int)(b & 0xffff)) << 16)); 
     } 

     public static short HIWORD(int a) 
     { 
      return ((short)(a >> 16)); 
     } 

     public static short LOWORD(int a) 
     { 
      return ((short)(a & 0xffff)); 
     } 
    } 
Powiązane problemy