繁体   English   中英

24 位无符号 Integer

[英]24 Bit Unsigned Integer

我开始使用 HART(高速可寻址远程传感器)协议,我发现了一些不同的东西,我试图理解它,更准确地说是 uint24。 我知道这个结构在内部使用 UInt32 来存储和大多数其他常见的预期 integer 功能,所以使用 24 位 integer 不会保存 memory。但我的问题是如何将 UInt32 转换为这种特定类型,我发现了这些行Javascript 中的代码,但我不知道那些左移的目的是什么。

var getUint24 = function(bytes)
{
    return (DataView(bytes.buffer).getUint16(0) << 8) + DataView(bytes.buffer).getUint8(0 + 2);
}

另外,我发现这个 function 将数字转换为 4 个字节。 我也不知道这些转移的目的是什么,但也许如果我理解这些我可以创建我自己的 function 版本,将一个简单的数字 ex: 4 转换为他的 uint24 版本。

/**
 *
 * @function ToBytesInt32 "Convert number to 4 bytes (eg: ToBytesInt32(2) returns 00 00 00 02"
 * @param {number} num The input value
 * @return {byte array}
 */
function ToBytesInt32BigEndian(num) {
    if (isNaN(num)) {
        throw "ToBytesInt32 received Nan! Called from: " +
        testUtils.StrReplace.caller.toString().split('\n')[0];
    }
    arr = [
        (num & 0xff000000) >> 24,
        (num & 0x00ff0000) >> 16,
        (num & 0x0000ff00) >> 8,
        (num & 0x000000ff)
    ];
    return arr;
}

如果有人能帮助我理解那些转变的目的,我会很感激,也非常欢迎 C/C++ 版本。

简答

  • left << shifting 是用零填充有效位,以便将来连接成单个值;
  • >>移位是将值段提取为较小数据类型的一部分(在应用掩码之后进行);

抽象的

Shift & sum 是当读/写帧小于值的长度时打包/解包值的方法。 假设我们有 4 位值: 1011 我们只能通过 2 位帧读取它: [10], [11]

假设我们从左到右阅读 stream。

# offset 0 bits
a = stream(0)      # a = 10
a << 2             # a = 1000

b = stream (2)     # b = 11

return a + b       # 1000 + 11 = 1011

你还应该注意 BE/LE (Big/Little Endian)。 在不同的字节序中,值1011可能在 stream 中显示为10, 1111, 10

getUint24 示例

getUint24示例中,我们将 24 位值打包为[16 bit, 8 bit]之类的序列。 让我们将其绘制为[XY, Z] ,其中单个字母为 1 个字节。

# offset 0 bytes
a = DataView(bytes.buffer).getUint16(0)      # a = XY
a << 8                                       # a = XY0

# offset 2 bytes
b = DataView(bytes.buffer).getUint8(2)       # b = Z

return a + b                                 # XY0 + Z = XYZ

再次bytes.buffer可以将值保存为[XY, Z][Z, XY] getUintX(offset)向我们隐藏了这些细节。 但是如果你想编写自己的转换器,你需要调查你的情况是什么格式。

ToBytesInt32BigEndian 示例

在这里,我们看到了打包值的另一个问题——应用掩码。

例如,我们有 32 位值AB CD EF 12 我们可以应用掩码来提取所需的值段。

例如,如果我们有 3 位值011并且想要获取第二位的值,我们需要应用 &-mask,其中针对1评估的主题位保留原始值,而针对0评估的 rest 位将任何值转换为0

masked    = 011 & 010    # 010
bit_value = masked >> 1  # 001

与我们的ABCDEF12一样

x = 0xABCDEF12 & 0xFF000000   # x = 0xAB000000
x >> 24                       # x = 0x000000AB
...

这样我们将得到数组[0xAB, 0xCD, 0xEF, 0x12] 没有移动我们得到数组[0xAB000000, 0x00CD0000, 0x0000EF00, 0x00000012]这不是我们想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM