当前位置: 首页 > 知识库问答 >
问题:

C整数除法如何处理极限值和负值?

楚丰羽
2023-03-14

我在C中遇到了一些关于整数除法的奇怪结果。我正在尝试计算:-2147483648/-1。

我得到的是3种不同情况下的3种不同结果:

int foo(int numerator, int denominator) {
    int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt

    cout << res << endl;
}

int main() {
    int res = -2147483648 / -1;
    cout << res << endl;               // prints -2147483648
    cout << -2147483648 / -1 << endl;  // prints 2147483648
    foo(-2147483648, -1);
    return 0;
}

为什么整数除法运算在不同的情况下产生不同的结果?

共有3个答案

解晟睿
2023-03-14
int res = -2147483648 / -1;
cout << res << endl;               // prints -2147483648
cout << -2147483648 / -1 << endl;  // prints 2147483648
int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt

请注意,没有负整数文本。

没有负整数文字。-1等表达式将一元减运算符应用于文字表示的值,这可能涉及隐式类型转换。

文字值2147483648大于int的最大值,因此其类型将为long(或long-long,具体取决于实现)。然后,-2147483648的类型是长的,计算结果(-2147483648/-1)也是长的。

对于第一种情况,类型为长的结果被隐式转换为int,但它大于int的最大值,结果是实现定义的。(结果似乎是根据此处表示(2的补码)的规则进行包装的,因此您得到的结果是2147483648)

对于第二种情况,带有long类型的结果直接打印出来,因此您得到正确的结果。

对于第三种情况,您正在对两个int进行计算,结果不能符合结果类型(即int),发生了有符号整数算术运算溢出,行为未定义。(此处产生SIGFPE,算术异常中断。)

松英喆
2023-03-14

您的结果可能是INT\u MAX 1,换句话说,它可能溢出。这是未定义的行为,任何事情都可能发生。例如,编译器可能会完全拒绝代码。

(系统可能具有INT\u MAX

麻昌翰
2023-03-14

编译器将文本2147483648/-1计算为2147483648,数据类型的宽度足以容纳该值。

直接打印文本时,它会正确打印值。

当文本存储在res中时,它将转换为int。在您的系统上,int的宽度为32位。值2147483648不能表示为32位有符号整数,因此强制转换会导致溢出。在您的html" target="_blank">系统上,此溢出导致值为2147483648(可能是使用了2的补码)。

最后,当尝试在运行时执行除法时(在foo函数中),由于溢出而发生SIGFPE异常(因为int数据类型不能表示结果)。

请注意,所有这三个选项都依赖于平台相关行为:

  • 事实上,当文字计算溢出时,编译器不会生成任何错误(或其他问题),只使用足够大的数据类型来保存结果
  • 存储文本时,int溢出会生成特定的值(没有其他问题)
  • 在运行时溢出时引发SIGFPE异常的事实
 类似资料:
  • 问题内容: -1 / 5整数除法应该返回什么?我对此行为完全感到困惑。我认为数学上应该为0,但是python和ruby返回-1。 为什么不同的语言在这里表现不同?请有人解释。谢谢。 问题答案: 简短的答案: 语言设计者可以选择在进行整数除法时,其语言是四舍五入为零,负无穷大还是正无穷大。不同的语言做出了不同的选择。 长答案: Python和Ruby的语言作者都认为向负无穷大舍入比向零四舍五入更有意

  • 我想问您,除了像(大小为30个元素)这样一开始就设置数组元素数的限制之外,是否还有一种方法可以在java中设置数组元素数的限制。您能在1到10个元素之间设置限制吗? (或者类似的东西)。 我的第二个问题也许更可行的是,你能不能给元素本身设置一个限制,比如当你需要在之后对它们进行排序时,如果一个元素>=100就会给出错误。类似于:

  • 基本上,当用户输入一个数字列表(当用户输入0时停止)时,输出将告诉最小整数、奇数整数和和负整数计数。我对负数的计数是正确的,但我遇到的问题是,奇数的和只有当数为正时才相加,最小整数总是为0。这是我的密码

  • 为了前任。数字返回而不是

  • 问题内容: 我正在使用MySQL存储财务资料,并使用数据来构建每个帐户的所有交易记录等。出于性能方面的考虑-为了防止用户被庞大的表格所淹没-我对结果进行了分页。 现在,作为注册的一部分,我将显示该帐户的余额。因此,如果我每页显示20个事务,而我显示第二页,则使用如下数据: 事务0-19: 忽略它们-它们比正在查看的页面要新。 交易20-39: 从中选择所有内容-它们会显示出来。 事务40-??:

  • 我的理解是,数字是用两者的恭维来否定的,我的理解是:!num+1。所以我的问题是,这是否意味着,对于变量'foo'=1,否定的'foo'将与变量'bar'=255完全相同。如果我们检查-'foo'=='bar'或-'foo'==255,我们会得到它们相等吗?我知道有些语言,如Java,保留一个符号位--所以比较会产生假。没有的语言呢?我假设汇编程序/本机没有符号位。 我的最后一个问题是,对于其他的