带符号整数的除法与余数

复习C++ Prime 4th的时候,看见书上对/和%操作符有以下描述:

For both division (/) and modulus(%), when both operands are positive, the result is positive (or zero). If both operands are negative, the result of division is positive (or zero) and the result of modulus is negative (or zero). If only one operand is negative, then the value of the result is machine-dependent for both operators. The sign is also machine-dependent for modulus; the sign is negative (or zero) for division :

 21 %  6;  // ok: result is 3
 21 %  7;  // ok: result is 0
-21 % -8;  // ok: result is -5
 21 % -5;  // machine-dependent: result is 1 or -4
 21 /  6;  // ok: result is 3
 21 /  7;  // ok: result is 3
-21 / -8;  // ok: result is 2
 21 / -5;  // machine-dependent: result -4 or -5

这段隐晦难懂的文字结合代码转换成表格后依然让人难以理解:

aba / ba % b
>0>0>=0,取值可唯一确定>=0,取值可唯一确定
<0<0>=0,取值可唯一确定<=0,取值可唯一确定
>0<0<=0,取值由实现决定符号和取值均由实现决定
<0>0<=0,取值由实现决定符号和取值均由实现决定


于是我下载了C++ Prime 4th出版时C++最新版本(C++03)的ISO 标准文档,在章节5.6 Multiplicative operators下找到了如下叙述:

The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.

也就是说对于整数除法和取余,C++03只确保以下两点:

( a / b ) * b + a % b = a ( b != 0 )。
a % b >= 0 ( a >= 0 && b > 0 )。

在经典和标准的描述中,都指出了余数的符号,却没有提及更容易让人理解的取整方法。
为此,我根据数学意义上的公式“商×除数+余数=被除数”做出了不同取整方法下,a和b的符号与a%b的符号的对应图:

这里写图片描述

根据这些图表,从取整方法的角度,可以得出以下结论:
标准:在操作数均为正数时向下取整(此时也是向零取整),其余情况由实现决定。
经典:在操作数符号相同时向下取整(此时也是向零取整),异号情况由实现决定。

经典与标准对操作数均为负数时描述的不一致让我迷惑,莫非是作者的一时疏忽?然而当我在C++ Prime 5th中的相应章节找到以下叙述时顿感纳闷:

In a division, a nonzero quotient is positive if the operands have the same sign and negative otherwise. Earlier versions of the language permitted a negative quotient to be rounded up or down; the new standard requires the quotient to be rounded toward zero (i.e., truncated).

“早期的语言标准允许负数商向上取整或向下取整”这一句岂不是暗示在操作数符号相同时取整方法是有明确规定的?

也许是Stanley B. Lippman连错了两次?

另外,C++11中已经规定,整数除法一律采用向零取整:

For integral operands the / operator yields the algebraic quotient with any fractional part discarded ( This is often called truncation towards zero. );

这一点在上述的C++ Prime 5th的叙述中也有提到。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值