将数据类型'long'转换为字节数组

时间:2011-08-26 08:30:36

标签: c# arrays serialization byte

我必须将值(C#中的double / float)转换为字节并需要一些帮助。

//数据类型长4byte -99999999,99到99999999,99
//数据类型长4byte -99999999,9至99999999,9
//数据类型短2byte -999,99到999,99
//数据类型短2byte -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变量也得到8字节,即99951(我将不包括ToString()样本)。

如果值甚至“更短”,这意味着-999,99 - 999,99,它只需要2个字节的空间。
[结束编辑]

5 个答案:

答案 0 :(得分:23)

您检查过BitConverter

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

希望这就是你正在寻找的东西

答案 1 :(得分:6)

尝试以这种方式:

long l = 4554334;

byte[] bA = BitConverter.GetBytes(l);

答案 2 :(得分:6)

请注意,在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),范围是a(带符号)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位。

答案 3 :(得分:1)

long longValue = 9999999999L;

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

        bytes = BitConverter.GetBytes(longValue);

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

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

答案 4 :(得分:1)

正如其他答案所指出的,您可以使用BitConverter来获取基元类型的字节表示。

你说在你居住的当下世界中,有一种责任在于尽可能简洁地表示这些值 ,在这种情况下你应该考虑variable length encoding(尽管那个文件可能是有点抽象)。

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