我可以依赖C中的%(modulo)运算符来表示负数吗?
使用GCC:
printf("%i \n", -1 % (int)4); printf("%u \n", -1 % (unsigned int)4);
输出:
-1 3
我可以跨平台依赖这种行为吗? 我应该明确定义MOD
和REM
宏以确保不会改变吗?
从C99开始, %
的结果需要被克里斯·多德引用为0 。
在C99标准之前, %
运算符对负数的行为是实现定义的 。
当整数被划分并且除法不精确时,如果两个操作数都是正数,则
/
运算符的结果是小于代数商的最大整数,并且%
运算符的结果是正数。 如果任一操作数为负 ,则/
运算符的结果是小于代数商的最大整数还是大于代数商的最小整数是实现定义的 ,这是%
运算符的结果的符号。 如果商a/b
是可表示的,则表达式(a/b)*b + a%b
应等于a
。ANSI C或ISO C是否指定
-5 % 10
应该是什么?
因此,如果您的目标是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)这通常被称为’截断为零”
这意味着鸿沟总是向0舍入,所以你可以依赖它。
请注意,这与C ++ 03标准不同。
你的第二行执行无符号除法,在除法之前将值-1
转换为unsigned int
。 这总是小于2的幂,因此也很明确。
mod(%)多年来一直是C和C ++标准的一部分。 我不确定你可以在C ++中重载它。 所以,你可以依靠它。