2011-08-26 17 views
15

tengo que convertir los valores (doble/flotador en C#) en bytes y de necesitar algo de ayuda ..

// tipo de datos a largo 4byte -99999999,99 a 99999999,99
// tipo de datos a largo 4byte -99999999,9 a 99999999,9
// tipo de datos corta 2byte -999,99 a 999,99
// tipo de datos corta 2byte -999,9 a 999,9

En mi " mundo en casa "simplemente lo encadenaría y ASCII.GetBytes().

Pero ahora, en este mundo, tenemos que hacer menos espacio posible.
Y de hecho que '-99999999,99' toma 12 bytes en lugar de 4! si es un tipo de datos 'largo'.Convertir tipo de datos 'largo' de matriz de bytes

[EDIT]
Debido al poco de ayuda y contesto que adjuntar algunos resultados aquí,

long lng = -9999999999L; 
byte[] test = Encoding.ASCII.GetBytes(lng.ToString()); // 11 byte 
byte[] test2 = BitConverter.GetBytes(lng);    // 8 byte 
byte[] mybyt = BitConverter.GetBytes(lng);    // 8 byte 
byte[] bA = BitConverter.GetBytes(lng);     // 8 byte 

Hay todavía tiene que ser un detalle izquierda para averiguar. El lng-variabel obtuvo 8 bytes incluso si contiene valores más bajos, es decir, 99951 (no incluiré la muestra ToString()).

Si el valor es incluso "más corto", lo que significa -999,99 - 999,99 solo ocupará 2 bytes de espacio.
[EDIT FIN]

+0

Sabes que long y short son de tipo integral, entonces no hay decimales, ¿verdad? ¡Y que un largo es 8 bytes, no 4! Eso es "int". – xanatos

+1

Me sorprende cuántas respuestas hay cuando la pregunta ni siquiera tiene sentido. ¿Qué tiene él y qué está tratando de obtener? –

+0

@xanatos Vale la pena mencionar su punto. Los valores son flotantes al principio (pero esa es otra pregunta). – Independent

Respuesta

5

Tenga en cuenta que en 2 bytes solo puede tener 4 completos digitos + signo, y en 4 bytes solo puedes tener 9 dígitos + signo, así que tuve que escalar tus prerrequisitos en consecuencia.

public static byte[] SerializeLong2Dec(double value) 
{ 
    value *= 100; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -999999999.0 || value > 999999999.0) 
    { 
     throw new ArgumentOutOfRangeException(); 
    } 

    int value2 = (int)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeLong2Dec(byte[] value) 
{ 
    int value2 = BitConverter.ToInt32(value, 0); 
    return (double)value2/100.0; 
} 

public static byte[] SerializeLong1Dec(double value) { 
    value *= 10; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -999999999.0 || value > 999999999.0) { 
     throw new ArgumentOutOfRangeException(); 
    } 

    int value2 = (int)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeLong1Dec(byte[] value) { 
    int value2 = BitConverter.ToInt32(value, 0); 
    return (double)value2/10.0; 
} 

public static byte[] SerializeShort2Dec(double value) { 
    value *= 100; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -9999.0 || value > 9999.0) { 
     throw new ArgumentOutOfRangeException(); 
    } 

    short value2 = (short)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeShort2Dec(byte[] value) { 
    short value2 = BitConverter.ToInt16(value, 0); 
    return (double)value2/100.0; 
} 

public static byte[] SerializeShort1Dec(double value) { 
    value *= 10; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -9999.0 || value > 9999.0) { 
     throw new ArgumentOutOfRangeException(); 
    } 

    short value2 = (short)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeShort1Dec(byte[] value) { 
    short value2 = BitConverter.ToInt16(value, 0); 
    return (double)value2/10.0; 
} 

Así que está claro, el rango de un (firmado) cortos (16 bits) es 32.768 a 32.767 por lo que es bastante claro que sólo tiene 4 dígitos completos más un pequeño pedazo (el 0-3) , el rango de un (firmado) int (32 bits) es -2,147,483,648 a 2,147,483,647, por lo que está bastante claro que solo tiene 9 dígitos completos más una pequeña pieza (el 0-2). Yendo a un (firmado) largo (64 bits) tiene -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 por lo que 18 dígitos más una pieza (grande). Al usar puntos flotantes, pierdes precisión. Un flotador (32 bits) tiene una precisión de alrededor de 7 dígitos, mientras que un doble (64 bits) tiene una precisión de alrededor de 15-16 dígitos.

15

Ha comprobado BitConverter

long lng =-9999999999L; 
byte[] mybyt = BitConverter.GetBytes(lng); 

esperanza de que esto es lo que está buscando

+0

Tenga en cuenta que el resultado depende del endianness de su máquina. – mpartel

5

tratar de hacerlo de esta manera:

long l = 4554334; 

byte[] bA = BitConverter.GetBytes(l); 
1
long longValue = 9999999999L; 

     Console.WriteLine("Long value: " + longValue.ToString()); 

     bytes = BitConverter.GetBytes(longValue); 

     Console.WriteLine("Byte array value:"); 

     Console.WriteLine(BitConverter.ToString(bytes)); 
1

Como han señalado las otras respuestas, puede usar BitConverter para obtener la representación de bytes de los tipos primitivos.

Usted ha dicho que en el mundo actual que habitan, hay una responsabilidad en la representación de estos valores como concisamente como sea posible, en cuyo caso se debe considerar variable length encoding (aunque ese documento puede ser un poco abstracto).

Si decide este enfoque es aplicable a su caso yo sugeriría mirar cómo el proyecto Protocol Buffersrepresents scalar types ya que algunos de estos tipos son codificados utilizando la codificación de longitud variable que produce una salida más corta si el conjunto de datos favorece menores valores absolutos. (El proyecto es de código abierto bajo New BSD license, por lo que podrá aprender la técnica empleada desde source repository o incluso utilizar la fuente en su propio proyecto.)

Cuestiones relacionadas