gpt4 book ai didi

c# - 在 C# 中设计比特流

转载 作者:太空狗 更新时间:2023-10-29 23:19:28 25 4
gpt4 key购买 nike

我正在查看名为 BitStream 的 C# 库,它允许您向标准 C# Stream 对象写入和读取任意数量的位。我注意到在我看来是一个奇怪的设计决定:

将位添加到空字节时,这些位将添加到字节的 MSB。例如:

var s = new BitStream();
s.Write(true);
Debug.Assert(s.ToByteArray()[0] == 0x80); // and not 0x01

var s = new BitStream();
s.Write(0x7,0,4);
s.Write(0x3,0,4);
Debug.Assert(s.ToByteArray()[0] == 0x73); // and not 0x37

但是,当引用数字中的位作为输入 时,输入数字的第一位是 LSB。例如

//s.Write(int input,int bit_offset, int count_bits)
//when referencing the LSB and the next bit we'll write
s.Write(data,0,2); //and not s.Write(data,data_bits_number,data_bits_number-2)

这对我来说似乎不一致。因为在这种情况下,当像前面的例子一样“逐渐”复制一个字节时(前四位,然后是后四位),我们不会得到原始字节。我们需要“向后”复制它(首先是最后四位,然后是前四位)。

我缺少那种设计的原因吗?具有这种行为的比特流的任何其他实现?其设计考虑因素是什么?

看来 ffmpeg 比特流的行为方式我认为是一致的。查看它在 OR 使用 the put_bits function 中的 src 指针之前将字节移动的数量。

作为旁注:

添加的第一个字节,是字节数组中的第一个字节。例如

var s = new BitStream();
s.Write(0x1,0,4);
s.Write(0x2,0,4);
s.Write(0x3,0,4);
Debug.Assert(s.ToByteArray()[0] == 0x12); // and not s.ToByteArray()[1] == 0x12

最佳答案

这里有一些额外的注意事项:

在 bool 值的情况下 - 只需要一位来表示真或假。当该位被添加到流的开头时,位流为“1”。当您将该流扩展到字节长度时,它会强制将零位填充到流的末尾,即使这些位不存在于流的开头。流中的位置是重要的信息,就像位的值一样,“1000000”或 0x80 的位流保证了流的后续读者可能认为他们读取的第一个位是添加的第一个位的期望。

其次,其他数据类型(如整数)需要更多位来表示,因此它们将在流中占用比 bool 值更多的空间。当不同大小的数据类型未按字节边界对齐时,在同一流中混合不同大小的数据类型可能会非常棘手。

最后,如果您使用的是 Intel x86,则您的 CPU 架构是“小端”,这意味着 LSB 优先,就像您描述的那样。如果您需要将值存储在流中作为 big-endian,您需要在代码中添加一个转换层 - 类似于您在上面显示的内容,您一次将一个字节按您想要的顺序插入流中.这很烦人,但如果您需要与大端 Unix 框互操作或协议(protocol)规范可能需要,则通常需要这样做。

希望对您有所帮助!

关于c# - 在 C# 中设计比特流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1391984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com