整数除法在C ++中用负数舍入

时间:2008-11-26 06:06:28

标签: c++ rounding

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

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

4 个答案:

答案 0 :(得分:22)

根据2008年5月的修订版,

你是对的:

  

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

注75说:

  

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

有可能C ++在这方面会落后于C.目前看来,它尚未定义,但他们着眼于改变它。

我和Stroustrup以及委员会成员在同一个部门工作。事情需要时间才能完成,而其无休止的政治。如果它看起来很傻,那可能就是。

答案 1 :(得分:18)

作为对其他答案的更新:

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

  

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

注意80个州(请注意,注释是非规范性的):

  

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

第4点继续说明:

  

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

可以证明a%b的符号与a的符号相同(非零时)。

答案 2 :(得分:7)

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

答案 3 :(得分:-2)

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

给定int x,int y

如果int i1 = x / y和    int i2 = x%y

然后y * i1 + i2必须为x

所以这不是标准,但这只有一种可能的方式。如果任何标准允许它采用任何其他方式,则标准是错误的,这意味着语言被破坏。