2011-08-26 31 views
15

我得值(双/漂浮在C#)转换为字节,需要一些帮助..

//数据类型长4个字节的-99999999,99到99999999,99
//数据类型长4个字节的-99999999,9到99999999,9
//数据类型短2字节-999,99至999,99
//数据类型短2字节-999,9到999,9

在我的“世界在家“我只是将它和ASCII.GetBytes()串起来。

但现在,在这个世界上,我们必须减少可能的空间。
事实上,'-99999999,99'需要12个字节而不是4个!如果它是'长'数据类型。转换数据类型“长”到字节数组

[编辑]
由于一些帮助和回答我在这里附上了一些成果,

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 

目前还是要一个细节留下来一探究竟。即使lng-variabel保持较低的值,即99951(我将不包括ToString()样本),它也得到了8个字节。

如果该值甚至“更短”,即-999,99-999,99,则只需要2个字节的空间。
[编辑完]

+0

你知道多空是整数类型,所以没有小数,对不对?而长的是8字节,而不是4!那是“int”。 – xanatos

+1

当问题甚至没有意义时,我惊讶地发现有多少个答案。他得到了什么,他想得到什么? – 2011-08-26 08:54:20

+0

@xanatos你的观点值得一提。这些值在开始时是浮动的(但这是另一个问题)。 – Independent

回答

5

请注意,在2个字节中,只能有4个满数字+符号,并且在4个字节中只能有9个数字+符号,所以我必须相应地缩放您的先决条件。

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

所以这很明显,的范围(签字)短(16位)-32,768到32,767所以这是很清楚,你只需要4个全数字加一小片(0-3) ,一个(带符号的)int(32位)的范围是-2,147,483,648到2,147,483,647,所以很明显你只有9个完整的数字加上一小块(0-2)。去(签名)长(64位),你有-9,223,372,036,854,775,808到9,223,372,036,854,775,807,所以18位数字加上一个(大)段。使用浮点数会降低精度。一个浮点数(32位)的准确度约为7位,而一个双精度数(64位)的精度约为15-16位。

15

你检查BitConverter

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

希望这是你在找什么

+0

请注意,结果取决于您的机器的字节顺序。 – mpartel

5

尝试做这样:

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

正如其他答案指出的那样,您可以使用BitConverter来获取原始类型的字节表示。

你说,你居住在当今世界,没有对代表这些数值简洁成为可能,在这种情况下,你应该考虑variable length encoding(尽管该文件可能是一个有点抽象)的责任。

如果你决定这个方法适用于你的情况我建议看如何Protocol Buffers项目represents scalar types一些这些类型的使用,如果数据集有利于较小的绝对值产生短输出可变长度编码编码。 (该项目开放源代码为New BSD license,因此您将能够学习从source repository采用的技术,甚至可以在您自己的项目中使用该源代码。)