我正在做一个项目,我需要在字节级别处理整数。由于节省空间是首要考虑因素,我只需要非常小的(和可变长度的整数)。
有没有办法可以将 int '4096' 转换为 3 个字节?或 '1053' 成 2 个字节?
显然我可以手动执行 = (byte[0] * 256) + (byte[1]),但我想知道是否有更简单的选项可以将 int 转换为 x 字节并再次返回?
你可以吗?当然。它会节省任何空间吗?也许,取决于你想做多少工作。您必须了解处理器是 32 位的,这意味着它有 4 个字节的寄存器,这就是它想要存储和访问事物的方式。要强制使用 3 字节“int”,您必须将其保存在字节数组中,并在使用前将其从数组中提取到对齐的地址。这意味着如果你把它存储得很短,编译器要么将它填充掉(你会失去你认为你已经创建的任何效率),要么它的读写速度会慢很多。
如果这是一个桌面应用程序,那么节省空间究竟是一个主要考虑因素,尤其是在每个元素 1 个字节时?元素访问的性能损失可能会改变您对一个字节的重要性的看法。
我会争辩说,如果那个 1 字节真的很重要,那也许,只是也许,你使用了错误的语言。首先,如果我不安装和使用 CLR,您将节省的字节数是很多字节。
旁注:你也会做一个转变,而不是一个乘法(尽管编译器可能会帮你)。
您可以进行可变长度整数编码。多年前的旧方法是使用每个字节的高位来表示整数继续到另一个字节。所以你每字节丢失一位,但获得小整数。这在每个最后一个字节都很重要的持久存储中非常有用。
示例:假设我们正在处理无符号整数,我们将有
int binary
0 00000000
1 00000001
...
127 01111111
128 00000001 10000000
129 00000001 10000001
...
255 00000001 11111111
256 00000010 10000000
...
16383 01111111 11111111
16384 00000001 10000000 10000000
所以 0-127 占用 1 个字节, 128-16383 占用 2 个字节,依此类推...
有关执行此操作的更复杂方法,请查看此页面
只是为了增加精神错乱,让我们在 C# 中使用旧的 C 风格联合技巧:
[StructLayout(LayoutKind.Explicit)]
struct OddUnion
{
/* The 32-bit integer value */
[FieldOffset(0)]
public int IntegerValue;
/* The bytes that overlap with it */
[FieldOffset(0)]
public byte Byte1;
[FieldOffset(1)]
public byte Byte2;
[FieldOffset(2)]
public byte Byte3;
[FieldOffset(3)]
public byte Byte4;
}
然后,当您想“转换”时,请执行以下操作:
OddUnion myOddUnion;
myOddUnion.IntegerValue = 4096;
Byte secondByte = myOddUnion.Byte1;
But that really only helps if you're looking to "save" the cost of bit-shifting out a single byte from a word. I haven't looked at the generated SMIL, so I don't know whether this is any cheaper in comparison to any other solution.
BitConverter.GetBytes
会给你字节。
和
BitConverter.ToInt32
将从字节中为您提供 32 位 int 。
你必须做一些位移。如果你使用 HEX 就容易多了,因为每个数字(我的意思是每个数字,但数字是基数 10,hexgit)代表四位。