![](/img/trans.png)
[英]How to code a modulo (%) operator in C/C++/Obj-C that handles negative numbers
[英]Can I rely on % (modulo) operator in C for negative numbers?
使用GCC:
printf("%i \n", -1 % (int)4);
printf("%u \n", -1 % (unsigned int)4);
输出:
-1
3
我可以跨平台依赖这种行为吗? 我是否应该明确定义MOD
和REM
宏,以确保这不会改变?
从C99开始, 必须将 %
的结果四舍五入为Chris Dodd引用的0 。
此前C99标准, %
运营商对负数的行为是实现定义 。
当整数相除并且除法不精确时,如果两个操作数都为正,则
/
运算符的结果为小于代数商的最大整数,并且%
运算符的结果为正。 如果操作数是负的 ,该结果是否/
操作者比代数商或最小整数比代数商更大的更少的最大整数是实现定义的 ,由于是的结果的符号%
运算符。 如果商a/b
是可表示的,则表达式(a/b)*b + a%b
等于a
。
因此,如果您以C99或更高版本为目标,则结果为“是” ,否则您将不能依靠它。
如果您需要一致的结果以及可移植到更旧的C标准的结果,则可以使用div
或ldiv
,而无需定义自己的MOD
和REM
有关div
, ldiv
和lldiv
函数的C99基本原理 :
因为当涉及负操作数时,C89具有实现定义的有义整数除法的语义,因此发明了C99中的div和ldiv和lldiv来为签名的整数除法和余数运算提供明确规定的语义。
C99标准说:
6.5.5乘法运算符
:
当整数被除时, /运算符的结果是代数商,其中任何小数部分都被舍弃了87) 。 如果商a / b是可表示的,则表达式
(a / b)* b + a%b等于a 。
:
87)这通常被称为``向零截断''
这意味着除法总是四舍五入,因此您可以依靠它。
请注意,这与C ++ 03标准不同。
您的第二行进行无符号除法,将除法之前的值-1
转换为unsigned int
。 这将始终小于2的幂,因此也有明确的定义。
多年来,模运算符( %
)已成为C和C ++标准的一部分。 我不确定您是否可以在C ++中重载它。 是的,您可以依靠它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.