【问题标题】:Signed integer addition, clarification needed有符号整数加法,需要说明
【发布时间】:2011-09-17 22:05:15
【问题描述】:

我有以下有符号整数:

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

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

【问题讨论】:

  • C 中带符号的 int 有多“大”?
  • 你有 4 位机器吗?如果有,是什么?
  • @agent - 英特尔 4004?没有C编译器。 :-)
  • 根据C语言第二版,4位机器一般应该有4位int。我相信甚至没有强制要求 int 是 1 或 2 补码系统(1 补码意味着 1 位用作有符号标志,因此您会丢失一个负数但得到 -zero 作为回报)。
  • @Roalt:如果《C 编程语言》第二版真的这么说,那就错了。 K&R 2ed 应该包含 ANSI 标准 C,即 C89,但 C89 表示INT_MAX 的最小允许值为32767(2.2.4.2 数值限制)。所以int一定不能是4位类型。

标签: c math binary


【解决方案1】:

与流行的看法相反,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 补码机器上。并不是说你可能会遇到这样的机器......

这是一种特殊情况,因为获得 4 位整数类型的唯一方法是作为位域。一般来说,有符号整数算术的溢出是未定义的行为(6.5/5,“结果是......不在其类型的可表示值范围内”)。由于升级到int,您的示例中没有算术溢出,因此可用于实现的行为范围是有限的 - 不允许格式化您的硬盘驱动器。但是,如果您确实溢出了 int,那么您将完全受制于编译器。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • C 标准中没有规定二进制补码表示。
    • @BatchyX:没有,但正如我所写:“在您正在使用的系统中”。如果 OP 将 1101 解释为二进制补码表示,则结果在 4 位系统中为 -3。由于整数至少是 16 位的,所以这个问题没有实际意义。我认为 OP 想要了解二进制补码表示和溢出算法。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      它是 13。C 中的ints 保证至少为 16 位。

      【讨论】:

      • 根据 The C Programming Language 第 2 版,第 157 页:“普通 int 对象具有主机架构建议的自然大小”。不过,它可能会因另一本书的版本而异。
      • @Roalt:K&R 不再定义语言,ISO/IEC 9899:TC3(又名 C99)定义了。或者 C89,如果你是微软的话。自 2nd 以来就没有 K&R 的版本,这是对该语言的一个很好的介绍,但它已经过时了。关于“自然尺寸”的文字在两个标准中都有,但您必须结合下限阅读它。如果您想真正变得挑剔,可以说这是标准中的一个缺陷,它 (a) 没有定义“自然大小”,和/或 (b) 似乎提出了相互矛盾的要求。实施者不太关注“自然大小”。
      【解决方案5】:

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

      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++?

      尤其是马丁的回答。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-06
        • 2014-10-08
        • 1970-01-01
        相关资源
        最近更新 更多