将长整型转换为字节以实现高效传输[重复]

问题描述 投票:0回答:1

我正在创建一个序列化格式,标头的一部分是正文的长度。

为此,我分配固定数量的字节(当前为 4),我想用它来存储尽可能长的数字。

因此,我想将

long
存储在
byte[]
中(我猜这可以称为基数 256?)。

这是我的代码:

long val = 25484394;
var encoded = new byte[4];

var max = 0L;

for (var i = 0; i < encoded.Length; ++i)
{
    max += (long)Math.Pow((int)byte.MaxValue, i);
}

if (val >= max)
    throw new ArgumentOutOfRangeException("value", $"{val} is too large to be encoded (max value is {max})");
    
    for (var i = encoded.Length - 1; i > 0; i--)
    {
//This line is wrong
        encoded[i] = (byte)(int)Math.Floor(val / Math.Pow(byte.MaxValue, i));
    }

我做错了什么?

c# byte long-integer
1个回答
0
投票

要将

long
值转换为字节数组(即基数 256),您需要使用按位运算。让我们一步步分解吧。

确保您没有超出限制: 4 字节(32 位)空间可以表示从

0
2^32 - 1
的值。因此,
max
应该是
2^32 - 1
(即
4294967295
),而不是您使用
byte.MaxValue
计算出的总和。

将长整型转换为字节: 要获取组成

long
的字节,您可以执行位掩码和移位。对于要提取的每个字节:

  • 使用掩码为
    &
    的按位与 (
    0xFF
    ) 来获取值的最低有效 8 位。
  • 将结果存储在字节数组中。
  • 将原始值右移 8 位以移至下一个字节。

这是代码的更正版本:

long val = 25484394;
var encoded = new byte[4];

// A 4-byte (32-bit) space can represent values from 0 to 2^32 - 1.
long max = (1L << 32) - 1;

if (val > max)
    throw new ArgumentOutOfRangeException("value", $"{val} is too large to be encoded (max value is {max})");

for (var i = 0; i < encoded.Length; i++)
{
    encoded[encoded.Length - 1 - i] = (byte)(val & 0xFF);
    val >>= 8; // Right shift the value by 8 bits
}

这是发生的事情:

  • 掩码
    0xFF
    将获得
    val
    的最低有效8位。
  • 在我们获取这些位并存储它们之后,我们将
    val
    右移 8 位,这样接下来的 8 位将处于下一次迭代的最低有效位置。这个过程一直持续到我们填满整个
    encoded
    数组。

注意: 处理

val
为负数或超出字节数组范围的情况很重要。上面的代码假设
val
始终为非负数,并且您正在检查最大允许值。如果
val
有可能为负,您需要为此添加另一项检查。

© www.soinside.com 2019 - 2024. All rights reserved.