模数运算符更改

Chu*_*dad 4 c++ modulus

C++ 03状态中的$ 5.6/4 - "如果两个操作数都是非负的,那么余数是非负的;如果不是,则余数的符号是​​实现定义的74).

注74是

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

C++ 0x状态 -

$ 5.6/4-"对于积分操作数,/运算符产生代数商,丢弃任何小数部分; 79如果商a/b在结果类型中可表示,(a/b)*b + a%b则等于a.

注79说

这通常被称为截断为零.

所以我有两个问题:

  • 有人可以解释这个"截断为零"的概念吗?

  • 具有负操作数的模数是否在C++ 0x中定义为行为?

Phi*_*ter 6

截断为零意味着通过选择接近零的下一个整数将实数转换为整数.等效地,您将数字写下来,并忽略小数点后的所有内容,无论数字是正数还是负数.

考虑11/4 = 2.75 - 如果你将此截断为零,则得到2.

考虑-11/4或11/-4 = -2.75 - 如果你将此截断为零,则得-2.

对于某些数学运算来说,重要的是(a/b)*b + a%b == a.如果我们必须使这个方程成立,并且我们也接受整数除法截断为零,那么我们可以推导出运算%符的操作如下:

a == 11, b == 4:
a/b == 2, 2*4 + a%b == 11, therefore a%b == 3.

a == -11, b == 4:
a/b == -2, -2 * 4 + a%b == -11, therefore a%b == -3.

a == 11, b == -4:
a/b == -2, -2 * -4 + a%b == 11, therefore a%b == 3.

a == -11, b == -4:
a/b == 2, 2 * -4 + a%b == -11, therefore a%b == -3.
Run Code Online (Sandbox Code Playgroud)

起初可能会让人感到困惑,但C++ 0x正在a%b使用等式定义运算符的行为(a/b)*b + a%b == a.即使对于负数,该等式也成立,因此a%b定义为负数.