C中的无符号整数下溢

时间:2018-06-17 20:51:39

标签: c integer standards underflow

我在网站上看到了多个问题,解决了无符号整数溢出/下溢问题。 关于下溢的大多数问题都询问是否为无符号整数赋值;我不清楚当从另一个unsigned int中减去unsigned int时会发生什么情况,例如a - b结果为负数。该标准的相关部分是:

  

涉及无符号操作数的计算永远不会过度流动,因为无法用结果无符号整数类型表示的结果会以比结果类型可以表示的最大值大1的数量为模。

在这种情况下,您如何解释"减少" ?这是否意味着UINT_MAX+1 已添加到否定结果,直到>= 0为止?

我看到主要问题由this question解决(基本上说标准选择讨论溢出,但关于 modulo 的主要观点仍然存在对于下溢也是如此)但我现在还不清楚:

a-b的结果是-1;根据标准,操作-1%(UINT_MAX+1)将返回-1(如解释here);所以我们回到我们开始的地方。

这可能过于迂腐,但 modulo 是否意味着数学模数而不是C的计算模数?

3 个答案:

答案 0 :(得分:4)

首先,不会调用低于给定整数类型最小值的结果" underflow"在C.术语"下溢"保留用于浮点类型,意味着完全不同的东西。超出整数类型的范围总是溢出,无论您跨越的范围的哪一端。所以你没有看到语言规范谈论" underflow"在这种情况下,行动者并不真正意味着什么。

其次,你对#34;减少"这个词的含义是完全正确的。最终值是通过从"数学"中添加(或减去)UINT_MAX+1来定义的。结果,直到它返回unsigned int的范围。这与Euclidean" modulo"也是一样的。操作。

答案 1 :(得分:1)

您发布的标准部分谈到溢出,而不是下溢。

"这是否意味着UINT_MAX + 1被添加到否定结果,直到它>&0;"

你可以认为发生了什么。抽象地说,结果是一样的。已经有人问过类似的问题。查看此链接:Question about C behaviour for unsigned integer underflow了解更多详情。

另一种思考方式是,例如,-1原则上来自类型def func(row): x = row['column1'] y = row['column2'] if row['column3'] == 'orange': return x * 2.0 else: return y df['column2'] = df.apply(func, axis=1) print(df) index column1 column2 column3 0 0 2 5.0 apple 1 1 4 3.0 apple 2 2 6 12.0 orange 3 3 8 6.0 apple 4 4 10 20.0 orange (即4个字节,其中所有位都是1)。然后,当您告诉程序将所有这些位1解释为int时,其值将被解释为unsigned int

答案 2 :(得分:0)

在引擎盖下,加法或减法是按位并且符号独立。生成的代码可以使用相同的指令,而不管它是否已签名。解释结果的是其他运算符,例如> 0.做一点点添加或子,这会告诉你答案。 b0 - b1 = b111111111答案与标志无关。只有其他运算符才能将答案视为带符号类型的-1和无符号类型的0xFF。该标准描述了这种行为,但我总是发现最容易记住它是如何工作的,并推断出对我正在编写的代码的影响。

signed int adds(signed int a, signed int b)
{
    return a + b;
}

unsigned int addu(unsigned a, unsigned b)
{
    return a + b;
}


int main() {
    return 0;
}

- >

adds(int, int):
  lea eax, [rdi+rsi]
  ret
addu(unsigned int, unsigned int):
  lea eax, [rdi+rsi]
  ret
main:
  xor eax, eax
  ret