37

假设ab都是 类型int, 并且b非零。考虑a/b在以下情况下执行的结果:

  1. a并且b都是非负的。
  2. a并且b都是负面的。
  3. 恰好其中一个是阴性的。

在案例 1 中,结果向下舍入到最接近的整数。但是标准对案例 2 和案例 3 有什么规定?我在 Internet 上发现的一份旧草案表明它依赖于实现(是的,甚至是案例 2),但委员会倾向于使其始终“向零舍入”。有谁知道(最新)标准说什么?请仅根据标准回答,而不是根据什么是有意义的,或者特定的编译器做什么。

4

4 回答 4

26

根据 2008 年 5 月的修订,

你是对的:

二元 / 运算符产生商,二元 % 运算符产生第一个表达式除以第二个表达式的余数。如果 / 或 % 的第二个操作数为零,则行为未定义;否则 (a/b)*b + a%b 等于 a。如果两个操作数都是非负数,则余数是非负数;如果不是,则余数的符号是​​实现定义的75)。

注释 75 说:

根据正在进行的 ISO C 修订工作,整数除法的首选算法遵循 ISO Fortran 标准 ISO/IEC 1539:1991 中定义的规则,其中商始终向零舍入。

C++ 在这方面很有可能落后于 C。就目前而言,它是未定义的,但他们着眼于改变它。

我与 Stroustrup 在同一部门工作,并与委员会的一名成员一起工作。事情需要 AGES 才能完成,而且它无休止的政治化。如果这看起来很愚蠢,那可能是。

于 2008-11-26T06:24:00.417 回答
26

作为其他答案的更新:

C++11 的最后一个草案n3242与实际的 C++11 标准相同,在 5.6 第 4 点(第 118 页)中说明了这一点:

对于整数操作数, / 运算符产生代数商,并丢弃任何小数部分;(见注 80)

注释 80 状态(请注意,注释是非规范性的):

80) 这通常被称为向零截断。

第 4 点继续指出:

如果商 a/b 在结果类型中是可表示的,则 (a/b)*b + a%b 等于 a。

可以证明要求 的符号与a%b的符号相同a(当不为零时)。

于 2011-11-15T14:08:41.597 回答
9

只是一个评论。C++ 标准的当前工作草案确实纠正了“实现定义的”问题,并要求截断为零。是委员会的网页,是草案。问题在第 112 页。

于 2008-11-26T06:35:18.040 回答
-6

有时我们需要退后一步,看看它的数学:

给定 int x, int y

如果 int i1 = x/y 并且 int i2 = x%y

那么 y * i1 + i2 必须是 x

因此,这与标准无关,但可能只有一种方式。如果任何标准允许它以任何其他方式出现,那么标准是错误的,这意味着语言被破坏了。

于 2017-11-23T20:28:30.090 回答