2009-09-17 9 views

Respuesta

15

Es el mismo que en 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: Debido a que estoy en un buen estado de ánimo, aquí tienes. ¡Solo recuerda, los tipos inmutables son inmutables! Las funciones 'set' deben asignarse a algo.

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: Pensándolo bien, si usted realmente necesita hacer esto y no quiere que la sintaxis de todas partes, utilizar la solución de Michael. +1 a él por mostrarme algo nuevo.

+0

¡Gracias, muy rápido! –

+0

Si los necesita mucho, y si tiene nostalgia de C días, puede crear métodos estáticos para ellos, llamados LoWord(), HiWord(), LoByte() y HiByte(). Estoy sorprendido de que estas ol 'macros equivalentes no se hicieron de alguna manera parte de alguna clase .NET como Int. – mjv

+0

Esto usa la potencia de cálculo, que es un desperdicio. En tiempo de compilación, el patrón de bits deseado ya está en algún lugar de la pila y podemos decirle al compilador exactamente dónde está este patrón de bits, por lo que se puede copiar sin ningún cálculo. Use System.BitConverter para esto. –

23

conjunto:

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

get:

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

[EDIT]

C# tiene un excelente soporte para las variables que comparten la misma posición de memoria, y los bits que estructuran

fuente: 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: puesto que C# no tiene macro función, el enfoque anterior es con más prestaciones de pasar la variable a métodos/métodos de extensión

+6

+1 para DEADBEEF –

+1

+1 por mostrarme algo nuevo. Ahora tengo algo nuevo para abusar. –

3

supongo que no desea que los cálculos cuando se desea que el Hiword/Hibyte o LoWord/Lobyte, si un System.Int32 comienza en la dirección 100 (por lo que ocupa las direcciones 100 a 103), usted quiere como LoWord los dos bytes que comienzan en la dirección 100 y 101 y Hiword es la dirección 102 y 103

Esto se puede lograr utilizando la clase BitConverter. Esta clase no hace nada con los bits, solo usa las direcciones para devolver el valor solicitado.

Como el tamaño de los tipos int/long es diferente por plataforma, y ​​WORD y DWORD son un poco confusos, utilizo los tipos de sistema System.Int16/Int32/Int64. Nadie tendrá problemas para adivinar el número de bits en un System.Int32.

Con BitConverter puede convertir cualquier número entero a la matriz de bytes comenzando en esa ubicación y convertir una matriz de bytes de la longitud adecuada al entero correspondiente. No hay cálculos necesarios y ningún bit cambiarán,

Suponga que tiene un System.Int32 X (que es un valor DWORD en términos de edad)

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

Lo bueno es que esto funciona con todas las longitudes, que Don No tiene que combinar funciones como LOBYTE e HIORD para obtener el tercer byte:

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

Utilizo estas 2 funciones ...

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

Otra 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)); 
     } 
    } 
Cuestiones relacionadas