使用带符号整数的两种不同二进制表示形式进行编程

时间:2019-07-10 19:21:09

标签: c language-lawyer

根据标准,关于固定宽度的数据类型:

  

[7.20.1.1精确宽度整数类型] typedef名称intN_t   指定一个带符号的整数类型,其宽度为N,没有填充位,并且一个   二进制补码表示法

从标准[6.2.6.2整数类型]开始,数字也可以由符号和大小,1的补码或2的补码表示。

因此,根据标准,我们可以有一个程序,其中int32_t以2的补码表示形式,而int则以1的补码表示形式。现在,如果我们比较它们会发生什么?还是对他们两个都进行算术运算?整数提升规则将发生,但是给定两种不同的表示形式的编译器(不知道机器的int二进制表示形式)将如何构成结果?

2 个答案:

答案 0 :(得分:3)

int32_t不能保证存在于给定的平台上。大概,如果您有一个非二进制补码的体系结构,int32_t将不会被定义。

从7.20.1.1版开始描述精确宽度整数:

  

typedef名称intN_t指定一个带符号的整数类型,其宽度为N,没有填充位,并且用二进制补码表示。因此,int8_t表示这样的带符号整数类型,其宽度恰好为8位。

     

typedef名称uintN_t指定宽度为N并且没有填充位的无符号整数类型。因此,uint24_t表示这样的无符号整数类型,其宽度为   恰好是24位。

     

这些类型是可选的。但是,如果实现提供宽度为8、16、32或64位的整数类型,则没有填充位,并且(对于有符号类型)具有二的补码表示形式,它应定义相应的typedef名称。

如果出于某种原因要创建一台具有符号幅度或一补码体系结构的机器,并对其进行编译,并且该编译器决定选择创建精确宽度类型的选项,编译器编写者将发现自己想要对它们进行算术运算时必须将精确宽度的整数转换为本机整数类型,然后再转换回以存储在变量中。这可能尤其麻烦,因为与符号和幅度和一个人的补语相比,两个人的补语可以代表更广泛的值。

tl; dr:编译器可以有可能在不是二进制补码的平台上实现精确宽度的整数,但是实际上没有人会因为这样做是可选的而烦恼这样做的,实施效率会很低。

答案 1 :(得分:2)

即使编译器将使用两种不同的方式来表示整数,编译器仍将知道如何比较它们或如何在计算中使用它们。
这是由编译器必须遵守标准的相应其他部分来保证的,即定义了比较或计算的结果行为应如何。

C标准保留了许多实现细节,以允许创建高效的编译器。但是,结果行为已定义,编译器当然知道的实现细节无法更改。两种不同的整数表示形式通常会导致使用更复杂的方法来一起使用它们,也就是说,编译器供应商可能会避免使用这种形式。