负功率为2

时间:2017-06-29 10:30:24

标签: c types

我正在学习不同数据类型的特征。例如,该程序越来越多地使用四种不同格式打印2的幂:#include<stdio.h> int main(int argc, char *argv[]){ int i, val = 1; for (i = 1; i < 35; ++i) { printf("%15d%15u%15x%15o\n", val, val, val, val); val *= 2; } return 0; }

unsigned

有效。 2147483648升至integer-2147483648升至2147483647。但为什么它变得消极?

我有一个理论:是因为我们可以在32位机器上表示的最大有符号整数是{{1}}吗?如果是这样,为什么它会返回负数?

3 个答案:

答案 0 :(得分:5)

首先,您应该了解此程序是 undefined 。它会导致带符号的整数溢出,并在C标准中声明 undefined

技术原因是没有行为可以预测,因为负数允许不同的表示,并且表示中甚至可能有填充位

在您的情况下,您看到负数的最可能原因是您的机器使用 2补码(查找)来表示负数,而算术运算在没有溢出检查的位上。因此,最高位是符号位,如果您的值溢出到该位,它将变为负值。

答案 1 :(得分:2)

您描述的是由整数溢出引起的UB。由于行为未定义,任何事情都可能发生(“当编译器遇到[给定的未定义构造]时,让恶魔飞出你的鼻子是合法的”),但实际上发生了什么一些机器(我怀疑你的机器)是这样的:

您从int val = 1;开始。它以二进制形式表示0b00...1。每次val *= 2;该值乘以2,因此表示更改为0b00...10,然后更改为0b00...100,依此类推(1位每次移动一步) 。您上次val *= 2;获得0b100...。现在,使用2的补码(这是我猜你的机器使用的,因为它很常见),实际上-1 * 0b1000...的值是-2147483648

请注意,尽管这可能是您的计算机上真正发生的事情,但它不会被信任或被认为是&#34;权利&#34;要发生的事情,因为如前所述,这是UB

答案 2 :(得分:-1)

在此程序中,val值将溢出,如果它是32位机器,因为整数的大小是4个字节。现在,我们在数学中有两种类型的值,正面和负面,因此要进行涉及否定结果的计算,我们在C语言中使用符号表示,即intchar

让我们以char为例,范围-128到127,unsigned char范围0-255。 它告诉我,范围分为两部分用于签名表示。因此,对于任何已签名的变量,如果它超过其+ ve值的范围,则它将变为负值。就像char的情况一样,当值超过127时,它变为-ve。并且假设如果您向任何charunsigned char变量添加300,则会翻转并从零开始。

char a=2;
a+=300;

价值是多少?现在你知道char的最大值是255(总共256个值,包括零),所以300-256 = 44 + 2 = 46。
 希望这有帮助

相关问题