【问题标题】:Is Integer representation endian-depending?整数表示是否依赖于字节序?
【发布时间】:2018-02-06 18:04:01
【问题描述】:

Tanenbaum says 整数被“逐字”读取,因此,

显然,整数在 BE 和 LE 中的存储方式相同,而只有字符串是“逐字节”读取的。

但是,字节序描述了单词的表示方式 (source),这意味着不同的字节序 = 不同的单词存储。那为什么是一样的呢?

根据this 的问题,unsigned long long x = 0x0123456789ABCDEF 的存储方式不同:

01 23 45 67 89 AB CD EF // big endian vs
EF CD AB 89 67 45 23 01 // little endian

那么,那是真的吗?整数(或数字,就此而言)是不同的(逐字节)表示还是相同(全部)?

【问题讨论】:

  • "显然整数在 BE 和 LE 中的存储方式相同" --> Middle endian 没有得到尊重。
  • 在这里发布“这个问题”的相关部分,而不是仅仅链接它以增加清晰度。
  • @chux 好的,我明白了。我试着改写一下。

标签: integer endianness cpu-architecture data-representation


【解决方案1】:

整数(或数字,就此而言)是不同的(逐字节)还是相同的(总共)表示?

C 允许多种编码方式 - 有些编码比其他编码更常见。然而,所有这些都受到一些规则的约束。


以层级为例,使用signed int
在二进制中,这将是 111...111000000001,其中第一个 1 是符号位。

第 1 层:(位宽 N,值位 M)一个 "signed 整数占用 N 位。对于 signed 整数,只有一个符号位和M 值位和0个或更多(稀有)填充位。总计N。这3组和位的顺序没有定义。相反,>>+ 等操作是用抽象定义的数值规范。例如左移值加倍。M的值很大程度上决定了int的范围。

// common implementations.
int: N=32, M=31
int: N=16, M=15

第 2 层:(2 的补码、符号/大小或 1 的补码)从具有值为 1 的最低有效位开始顺序排列值位并且下一位的值为2,然后是 4,然后是 8,等等。压倒性的常见 2 的补码布局中的 符号 位的值为 -2M。其他布局主要用于历史用途。

// Common implementations include:
int: N=32, M=31, 2's complement
int: N=16, M=15, 2's complement

第 3 层:字节宽度

int 占用 N 位,但位/字节(最小可寻址单元)的数量通常为 8 位/字节,但也存在其他的,例如 16、64 和历史上的 9、18 等. 必须至少为 8。目前,考虑近乎普遍的选择是 8 位/字节。

// Common implementations include:
int: N=32, M=31, 2's complement, 4 bytes
int: N=16, M=15, 2's complement, 2 bytes

第 4 层:字节序。

对于多个字节的典型int 代码,int 上的最低可寻址字节是编码最低有效位还是最高有效位或其他?最常见的 2 个是 little endianbig endian,如 OP 所示。还存在其他稀有字节序。

// Common implementations include:
int: N=32, M=31, 2's complement, 4 bytes, big endian
int: N=32, M=31, 2's complement, 4 bytes, little endian
int: N=16, M=15, 2's complement, 2 bytes, little endian

例子

值为-512,第一个字节的值是多少?
二进制:111...1110_00000001,第一位为符号位。

-511--> 0xFF (int: N=32, M=31, 2's complement, 4 bytes, big endian)
-511--> 0x01 (int: N=32, M=31, 2's complement, 4 bytes, little endian)
-511--> 0x01 (int: N=16, M=15, 2's complement, 2 bytes, little endian)
-511--> 0xFE (int: N=16, M=15, 2's complement, 2 bytes, big endian)

【讨论】:

    【解决方案2】:

    显然整数在 BE 和 LE 中的存储方式相同

    不,他们不是;这就是字节序的全部意义所在。是的,每个整数都存储在 4 个字节中,但是如果您一次读取一个字节的 4 字节字,您会看到 little-endian 将最不重要的字节放在首位,而 big-endian 将最重要的字节放在前面单个整数表示中的字节优先。

    以您在问题中包含的long long 为例,另请参阅https://en.wikipedia.org/wiki/Endianness


    其他字节序也是可能的,例如PDP-endian actually exists。理论上,整数字节的任何加扰函数都是可能的,但除非您正在设计 Deathstation-9000,否则没有理由做任何奇怪的事情。 (并且绝对是做比大端或小端更奇怪的事情的原因,因为如果 32 位整数的一半的 16 位加载实际上得到低半或高半,那就太好了,不是其他两个字节的混合。)

    【讨论】:

    • "if you were to read that [integer] 4-byte word one byte at a time, you would see that little-endian puts the least-significant byte first" - 那么问题中的图像呢? jim smith 在 LE 中是相反的,但21 在 LE 和 BE 中都位于最右侧。
    • @Blauhirn:这就是整数在加载后出现在寄存器中的方式;它是解密的。如果您查看您发布的链接中的表版本,则这些列在 BE 表中标记为 0 1 2 3,在 LE 表中标记为 3 2 1 0。因此,在这两种情况下,字符串实际上都是按顺序存储的,但是逐字加载它会通过 CPU 的字节序加扰运行这些字节,并在寄存器中产生这种排列(其中 left 是左移的方向;寄存器不'没有字节顺序,只是移位)。
    猜你喜欢
    • 2020-12-15
    • 2014-07-20
    • 1970-01-01
    • 2023-03-30
    • 2018-07-22
    • 1970-01-01
    • 2015-09-22
    • 2015-01-09
    • 2017-02-21
    相关资源
    最近更新 更多