模运算符更改
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 中定义的行为吗?
$5.6/4 in C++03 states- "If both
operands are nonnegative then the
remainder is nonnegative;if not, the
sign of the remainder is
implementation-defined74).
where Note 74 is
According to work underway toward the
revision of ISO C, the preferred
algorithm for integer division
follows the rules defined inthe ISO
Fortran standard, ISO/IEC 1539:1991,
in which the quotient is always
rounded toward zero.
C++0x states -
$5.6/4- "For integral operands the / operator yields the algebraic quotient with any fractional part discarded;79 if the quotient a/b is representable in the type of the result,
(a/b)*b + a%b
is equal to a.
Note 79 says
This is often called truncation towards zero.
So I have two questions:
Can someone explain this concept of 'truncation towards zero'?
Is modulus with negative operands a defined behavior in C++0x?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(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
(b == 0
除外)定义了 a/b
,并且 < code>(a/b)*b + a%b == a,a%b
只有 1 个唯一解,因此 %
运算符对于所有 a
和 b
(b == 0
除外)也是很好的保护。
a) “朝零截断”仅仅意味着任何小数部分都被截掉。截断后的数字始终至少与原始数字一样接近 0,并且通常更接近原始数字。
这在负数中最为明显,但目标是让使用 /
和 %
与负数变得不那么棘手(因为目前,任何实现都可以处理它,但是它们选择)。 -7/4 可以有两种方式:-2 余数为 1,或 -1 余数为 -3。并且有编译器和处理器可以以两种方式处理它。由于 -7/4 实际上是 -1.75,“向零截断”会给你 -1,所以后一种方法是标准的。
b)
看起来就是这样。它始终是半定义的(“实现定义的”),但这看起来像是试图从一开始就定义什么应该是标准的。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
向零截断意味着通过选择下一个最接近零的整数将实数转换为整数。同样,您写下数字,并忽略小数点后的所有内容,无论数字是正数还是负数。
考虑 11/4 = 2.75 - 如果将其截断为零,则得到 2。
考虑 -11/4 或 11/-4 = -2.75 - 如果将其截断为零,则得到 -2。
对于某些数学运算来说,(a/b)*b + a%b == a 很重要。如果我们必须使这个方程成立,并且我们也接受整数除法向零截断,那么我们可以推导出
%
运算符的操作如下:一开始可能会令人困惑,但 C++ 0x 使用方程
(a/b)*b + a%b == a
定义a%b
运算符的行为。该方程甚至对于负数也成立,因此a%b
是针对负数定义的。Truncation towards zero means converting a real number to an integer by selecting the next integer nearest zero. Equivalently, you write the number down, and ignore everything after the decimal point, whether the number is positive or negative.
Consider 11/4 = 2.75 -- if you truncate this towards zero, you get 2.
consider -11/4 or 11/-4 = -2.75 -- if you truncate this towards zero, you get -2.
It's important for some maths operations that (a/b)*b + a%b == a. If we must make this equation hold, and we also accept that integer division truncates towards zero, then we can deduce the operation of the
%
operator as follows:It might be confusing at first, but C++0x is defining the behaviour of the
a%b
operator using the equation(a/b)*b + a%b == a
. This equation holds even for negative numbers, soa%b
is defined for negative numbers.