有符号整数加法,需要澄清

时间:2011-06-18 20:03:01

标签: c math binary

我有以下有符号整数:

(4bits)a = 6;
(4bits)b = 7;
(4bits)c;
c = a + b;

c = 13或c = -3? 如果我做二进制数学并假设它是一个4位数:  0110 + 0111 = 1101(-8 + 4 + 0 + 1)= -3

5 个答案:

答案 0 :(得分:10)

与普遍看法相反,C 具有4位整数类型。但是,它没有这些类型的对象,只有位字段(6.7.2.1/9,"位字段被解释为有符号或无符号整数类型,包括指定位数"):

#include <stdio.h>

typedef struct int4bit {
    signed int value:4;
} int4bit;

int main() {
    int4bit a, b, c;
    a.value = 6;
    b.value = 7;
    c.value = a.value + b.value;
    printf("%d\n", c.value);
}

我的编译器的这个程序的输出是-3然而标准不保证这一点。原因是表达式a.value + b.value具有类型int(因为整数提升规则,6.3.1.1 / 2)和值13.值13不能用4位有符号整数表示,并且因此,发生以下两种情况之一:实现定义的结果或实现定义的信号(6.3.1.3/3)。

简而言之,您所能做的就是检查编译器文档,或运行代码并查看它的作用。但是这个结果-3对于带有符号整数类型的2s补码表示的实现来说非常自然。

可以为13,因为13不在4位有符号整数可表示的值范围内。任何事情都是允许的,只要实施文件,例如它自然是-2,在1s&#39;补充机器没有溢出检查。并不是说你可能会遇到过这样的机器......

这是一种特殊情况,因为获得4位整数类型的唯一方法是作为位字段。通常,有符号整数运算的溢出是未定义的行为(6.5 / 5,&#34;结果是......不在其类型的可表示值的范围内&#34;)。由于促销int,您的示例中没有算术溢出,因此实施可用的行为范围有限 - 不允许格式化您的硬盘。但如果你溢出int,那么你完全受编译器的支配。

答案 1 :(得分:5)

如果您使用的系统中的整数是4位长,那么结果确实会溢出,结果将为-3。但是在C ints中至少是16位,因此结果将是13。

答案 2 :(得分:1)

操作的结果是特定于行为的。 C并没有强制要求架构必须使用二进制补码表示(即使几乎所有都是这样)。

但是你应该用更大的数字重写你的例子,因为这里的人们对你的“让我们假装int是4bit”感到困惑。

答案 3 :(得分:0)

它是13. {C}中的int s保证至少为16位。

答案 4 :(得分:0)

您是否在编译器中尝试过此操作?网上有一个免费的...

http://codepad.org/MHUee7hx

#include "stdio.h"

int main(int argc, char* argv)
{
  int a = 6;
  int b = 7;
  int c;
  c = a + b;
  printf("%i\n", c);
  return 0;
}
  

13

此外,C中没有4位int。如果您有4位int,则表示您没有使用符合标准的C版本。

请参阅此问题 - What is the difference between an int and a long in C++?

特别是马丁的答案。