2009-09-17 5 views

risposta

15

E 'lo stesso come in 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: Perché io sono di buon umore, qui si va. Ricorda, i tipi immutabili sono immutabili! Le funzioni 'set' devono essere assegnate a qualcosa.

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: Il secondo pensiero, se si ha realmente bisogno di fare questo e non si desidera la sintassi ovunque, usare la soluzione di Michael. +1 a lui per avermi mostrato qualcosa di nuovo.

+0

Grazie, molto in fretta! –

+0

Se hai bisogno di molto, e se hai nostalgia dei giorni C, puoi creare metodi statici per questi, chiamati LoWord(), HiWord(), LoByte() e HiByte(). Sono sorpreso che questi vecchi equivalenti non siano stati in qualche modo parte di alcune classi .NET come Int. – mjv

+0

Questo utilizza la potenza di calcolo, che è uno spreco. Al momento della compilazione il modello di bit desiderato è già da qualche parte nello stack e possiamo dire al compilatore esattamente dove questo modello di bit è, in modo che possa essere copiato senza calcoli. Usa System.BitConverter per questo. –

23

set:

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

get:

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

[EDIT]

C# ha un eccellente supporto per le variabili che condividono la stessa posizione di memoria, e bit strutturando

fonte: 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, 

     } 
    } 
} 

NOTA: visto che il C# non hanno funzione macro, l'approccio di cui sopra è più performante rispetto passare la variabile a metodi/metodi di estensione

+6

+1 per deadbeef –

+1

+1 per avermi mostrato qualcosa di nuovo. Ora ho qualcosa di nuovo da abusare. –

3

Credo che tu non vuoi che i calcoli quando si desidera che il Hiword/Hibyte o LoWord/Lobyte, se un System.Int32 inizia all'indirizzo 100 (quindi occupa l'indirizzo da 100 a 103), vuoi come LoWord i due byte che iniziano all'indirizzo 100 e 101 e Hiword è l'indirizzo 102 e 103

Ciò può essere ottenuto utilizzando la classe BitConverter. Questa classe non fa nulla con i bit, utilizza solo gli indirizzi per restituire il valore richiesto.

Poiché le dimensioni di tipi come int/long sono diverse per piattaforma e WORD e DWORD sono un po 'confusi, utilizzo i tipi System System.Int16/Int32/Int64. Nessuno avrà mai problemi a indovinare il numero di bit in un System.Int32.

Con BitConverter è possibile convertire qualsiasi numero intero di matrici di byte che iniziano su tale posizione e convertire una serie di byte della lunghezza corretta nel numero intero corrispondente. Non ci sono calcoli necessari e nessun bit cambieranno,

Supponiamo di avere uno System.Int32 X (che è un valore DWORD nei vecchi termini)

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

La cosa bella è che questo funziona con tutte le lunghezze, don Devo combinare funzioni come LOBYTE e HIORD per ottenere il terzo byte:

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

Io uso queste 2 funzioni ...

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

Un'altra alternativa

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)); 
     } 
    } 
Problemi correlati