【问题标题】:What are arithmetic underflow and overflow in C?什么是 C 中的算术下溢和上溢?
【发布时间】:2011-09-15 15:30:58
【问题描述】:

C 编程中算术下溢和上溢是什么意思?

【问题讨论】:

    标签: c math integer-overflow


    【解决方案1】:

    溢出

    来自http://en.wikipedia.org/wiki/Arithmetic_overflow

    当一个 计算产生的结果是 在幅度上大于一个 给定的寄存器或存储位置可以 存储或代表。

    例如:

    uint32_t x = 1UL << 31;
    x *= 2;  // Overflow!
    

    请注意,正如@R 在下面的评论中提到的,C 标准建议:

    涉及无符号的计算 操作数永远不会溢出,因为 无法表示的结果 得到的无符号整数类型是 减少模数是一 大于最大值 可以用结果来表示 输入。

    当然,这是“溢出”的一个相当特殊的定义。大多数人会将模减少(即环绕)称为“溢出”。

    下溢

    来自http://en.wikipedia.org/wiki/Arithmetic_underflow

    计算机程序中的条件 当一个真正的结果可能会发生 浮点运算在 幅度(即接近于零) 比可表示的最小值 作为一个普通的浮点数 目标数据类型。

    例如:

    float x = 1e-30;
    x /= 1e20; // Underflow!
    

    【讨论】:

    • 您的溢出示例在 C 标准语言中是错误的。无符号类型不能溢出.
    • @R.:“溢出”当然具有独立于 C 标准的易于理解的含义!但你是对的,所以我会在我的回答中包含这个事实。
    • 当人们说“整数溢出总是导致未定义的行为”之类的话时,这种区别主要是重要的。
    • unsigned char x = 0; x -= 1; 呢?这算不算下溢?
    • 我在Wikipedia 上发现它被称为“整数溢出”或“整数环绕”。它说: 请注意,在整数变量中存储太低的值(例如,尝试将 -1 存储在无符号整数中)被正确地称为整数溢出,或更广泛地说是“整数环绕”。术语下溢通常仅指浮点数,是一个单独的问题。 谢谢!
    【解决方案2】:

    计算机只使用 0 和 1 来表示数据,因此可以表示的值的范围是有限的。很多计算机使用32位来存储整数,所以这种情况下可以存储的最大无符号整数是2^32 -1 = 4294967295。但是第一位是用来表示符号的,所以,其实最大值是2^31 - 1 = 2147483647。

    超出允许范围的整数需要的位数超过可存储的位数的情况称为溢出。

    同样,对于实数,指数太小而无法存储会导致下溢。

    【讨论】:

      【解决方案3】:

      int 是 C 语言中最常见的数据类型,是 32 位数据类型。这意味着每个 int 在内存中都有 32 位。如果我有变量

      int a = 2;
      

      这实际上会在内存中表示为 32 位二进制数: 000000000000000000000000000000010.

      如果你有两个二进制数比如

      100000000000000000000000000000000

      100000000000000000000000000000000,

      它们的总和将是 100000000000000000000000000000000,即 33 位长。但是,计算机只取了 32 个最低有效位,它们全为 0。在这种情况下,计算机识别出总和大于 32 位可以存储的值,并给出溢出错误。

      下溢基本上是在相反方向发生的相同事情。 C 使用的浮点标准允许小数点后 23 位;如果数字的精度超过这一点,它将无法存储这些位。这会导致下溢错误和/或精度损失。

      【讨论】:

      • 计算机通常不会检查操作是否导致溢出。你从哪里得到 23 个?
      • int 不是 32 位数据类型。
      • @OliCharlesworth:在 IEEE 754 下,单精度浮点数具有 23 个(不是数字)有效位。还有一个隐式位,通常为您提供 24 位精度,但在下溢期间不适用,它使用次正规数来提供逐渐降低的精度。
      • 您对下溢的描述完全错误。浮点数由三个字段组成:符号、有效数(分数)和指数。有效数字中的位数决定精度(对于 32 位浮点数,大约 7 个十进制字符)。指数中的位数决定了可表示值的范围(从最小到最大)。小数点的位置由指数的值决定,与精度无关。当要存储的值的大小小于指数可以支持的最小值时,就会发生下溢。
      • @Oli Charlesworth:通常每个 CPU 在其状态寄存器中都有一个溢出标志。 (也许你的意思是 C 不关心这个)
      【解决方案4】:

      下溢完全取决于给定的算法和给定的输入数据,因此程序员没有直接控制。另一方面,上溢取决于程序员为每个人保留的内存空间量的任意选择堆栈,并且此选择确实会影响可能发生溢出的次数

      【讨论】:

      • 你把事情混在一起了:算术下溢和堆栈溢出并将它们放在一起,让你的答案充其量是混乱的。我也不确定我是否同意你的定义。
      • 您的回答只说它们之间有什么区别,但没有说 what 它们是什么;问题的标题是“什么是下溢和上溢
      猜你喜欢
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      相关资源
      最近更新 更多