$ 5.6 / 4在C ++ 03状态中 - “如果两者都有 操作数是非负的 余数是非负的;如果不是,则为 其余的标志是 实现定义 74)
注74是
根据正在进行的工作 修改ISO C,首选 整数除法算法 遵循ISO中定义的规则 Fortran标准,ISO / IEC 1539:1991, 其中商始终存在 向零舍入。
C ++ 0x状态 -
$ 5.6 / 4-“对于积分操作数,/运算符产生代数商,丢弃任何小数部分; 79 如果商a / b可在结果类型中表示,{{1等于a。
注79说
这通常被称为截断为零。
所以我有两个问题:
有人可以解释这个“截断为零”的概念吗?
具有负操作数的模数是否在C ++ 0x中定义了行为?
答案 0 :(得分: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.
一开始可能会让人感到困惑,但C ++ 0x使用等式a%b
来定义(a/b)*b + a%b == a
运算符的行为。该等式甚至适用于负数,因此a%b
定义为负数。
答案 1 :(得分:3)
a)考虑(±5)/(±3) -> ±1
。在数字行上:
(-5)/3 5/3
5/(-3) (-5)/(-3)
= =
-1.66 --> -1 1 <-- 1.66
v v v v
- + - - - + - - - + - - - + - - - + -
| | | | |
-2 -1 0 1 2
因此,舍入是朝零。
b)是的。由于a/b
现已为所有a
和b
(b == 0
除外)和(a/b)*b + a%b == a
定义,因此a%b
只有一个唯一解决方案,因此%
运算符也适用于所有a
和b
(b == 0
除外)。
答案 2 :(得分:1)
a)“截断为零”只是意味着任何小数部分被砍掉。截断的数字始终至少与原始数字一样接近0,并且通常比原始数字更接近。
这在负数中最为明显,但目标是使用/
和%
使用负数时不那么棘手(因为目前,任何实现都可以处理它,但是他们选择)。 -7/4可以被认为是两种方式:-2,余数为1,或-1,余数为-3。并且有编译器和处理器可以同时处理它。由于-7/4实际上是-1.75,“截断为零”会给你-1,所以后一种方式是标准的。
b)中 这就是它的样子。它始终是半定义的(“实现定义的”),但这似乎是尝试从一开始就定义标准内容。