转换数据类型“long”到字节数组

发布于 2024-12-01 19:11:29 字数 886 浏览 5 评论 0原文

我必须将值(C# 中的双精度/浮点)转换为字节并且需要一些帮助..

// 数据类型 long 4byte -99999999,99 到 99999999,99
// 数据类型 long 4byte -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,它也有 8 个字节(我不会包含 ToString() 示例)。

如果该值更“短”,即 -999,99 -- 999,99,则仅占用 2 个字节空间。
[编辑结束]

I have to convert values (double/float in C#) to bytes and need some help..

// Datatype long 4byte -99999999,99 to 99999999,99
// Datatype long 4byte -99999999,9 to 99999999,9
// Datatype short 2byte -999,99 to 999,99
// Datatype short 2byte -999,9 to 999,9

In my "world at home" i would just string it and ASCII.GetBytes().

But now, in this world, we have to make less possible space.
And indeed that '-99999999,99' takes 12 bytes instead of 4! if it's a 'long' datatype.

[EDIT]
Due to some help and answer I attach some results here,

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

There still have to be one detail left to find out. The lng-variabel got 8 byte even if it helds a lower values, i.e. 99951 (I won't include the ToString() sample).

If the value are even "shorter", which means -999,99 -- 999,99 it will only take 2 byte space.

[END EDIT]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

仙气飘飘 2024-12-08 19:11:29

您检查过 BitConverter

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

希望如此就是你正在寻找的

Have you checked BitConverter

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

hope this is what you are looking

平定天下 2024-12-08 19:11:29

尝试这样做:

long l = 4554334;

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

Try to do it in this way:

long l = 4554334;

byte[] bA = BitConverter.GetBytes(l);
前事休说 2024-12-08 19:11:29

请注意,在 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)。对于(有符号)long(64位),您有-9,223,372,036,854,775,808到9,223,372,036,854,775,807,所以18位数字加上一个(大)块。使用浮点数会降低准确性。浮点型(32 位)的精度约为 7 位数字,而双精度型(64 位)的精度约为 15-16 位数字。

Be aware that in 2 bytes you can only have 4 full digits + sign, and in 4 bytes you can only have 9 digits + sign, so I had to scale your prereqs accordingly.

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

So that it's clear, the range of a (signed) short (16 bits) is -32,768 to 32,767 so it's quite clear that you only have 4 full digits plus a little piece (the 0-3), the range of a (signed) int (32 bits) is −2,147,483,648 to 2,147,483,647 so it's quite clear that you only have 9 full digits plus a little piece (the 0-2). Going to a (signed) long (64 bits) you have -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 so 18 digits plus a (big) piece. Using floating points you lose in accuracy. A float (32 bits) has an accuracy of around 7 digits, while a double (64 bits) has an accuracy of around 15-16 digits.

稀香 2024-12-08 19:11:29

致所有阅读此问题及其答案的人。请注意:

//convert to bytes
long number = 123;
byte[] bytes = BitConverter.GetBytes(number);

//convert back to int64
long newNumber = BitConverter.ToInt64(bytes);

//numbers are different on x64 systems!!!
number != newNumber;

解决方法是检查您运行的系统:

newNumber = BitConverter.IsLittleEndian
    ? BitConverter.ToInt64(bytes, 0)
    : BitConverter.ToInt64(bytes.Reverse().ToArray(), 0);

To everyone reading this question and the answers. Please note that:

//convert to bytes
long number = 123;
byte[] bytes = BitConverter.GetBytes(number);

//convert back to int64
long newNumber = BitConverter.ToInt64(bytes);

//numbers are different on x64 systems!!!
number != newNumber;

The workaround is to check which system you run on:

newNumber = BitConverter.IsLittleEndian
    ? BitConverter.ToInt64(bytes, 0)
    : BitConverter.ToInt64(bytes.Reverse().ToArray(), 0);
初心 2024-12-08 19:11:29

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

您说过,在您所居住的当前世界中,有责任尽可能简洁地表示这些价值观,在这种情况下,您应该考虑可变长度编码(尽管该文档可能有点抽象)。

如果您认为此方法适用于您的情况,我建议您了解一下协议缓冲区 项目表示标量类型作为其中一些类型使用可变长度编码进行编码,如果数据集偏向于较小的绝对值,则会产生较短的输出。 (该项目是在 新 BSD 许可证下开源的,因此您将能够从源代码存储库学习所采用的技术,甚至使用您自己的源代码项目。)

As the other answers have pointed out, you can use BitConverter to get the byte representation of primitive types.

You said that in the current world you inhabit, there is an onus on representing these values as concisely as possible, in which case you should consider variable length encoding (though that document may be a bit abstract).

If you decide this approach is applicable to your case I would suggest looking at how the Protocol Buffers project represents scalar types as some of these types are encoded using variable length encoding which produces shorter output if the data set favours smaller absolute values. (The project is open source under a New BSD license, so you will be able to learn the technique employed from the source repository or even use the source in your own project.)

╰つ倒转 2024-12-08 19:11:29
long longValue = 9999999999L;

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

        bytes = BitConverter.GetBytes(longValue);

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

        Console.WriteLine(BitConverter.ToString(bytes));
long longValue = 9999999999L;

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

        bytes = BitConverter.GetBytes(longValue);

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

        Console.WriteLine(BitConverter.ToString(bytes));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文