使用GCC:
printf("%i \n", -1 % (int)4);
printf("%u \n", -1 % (unsigned int)4);
输出:
-1
3
我可以跨平台依赖此行为吗?我应该明确定义MOD
和REM
宏以确保不会更改吗?
答案 0 :(得分:4)
从C99起,%
的结果需要舍入为0 ,如Chris Dodd所引用。
在C99标准之前,%
运算符在负数上的行为是实现定义。
当整数被划分且除法不精确时,如果两个操作数均为正,则
/
运算符的结果是小于代数商的最大整数,%
运算符的结果为正。 如果任一操作数为负,/
运算符的结果是小于代数商的最大整数还是大于代数商的最小整数实现定义的< / strong>,这是%
运算符结果的符号。如果商a/b
可表示,则表达式(a/b)*b + a%b
应等于a
。
如果您定位C99或更新版本,结果是是,否则您无法依赖它。
如果您需要一致的结果与可移植性甚至更旧的C标准,您可以使用div
or ldiv
,无需定义自己的MOD
和REM
C99 rationale regarding div
, ldiv
, and lldiv
functions:
因为当涉及负操作数时,C89具有用于划分有符号整数的实现定义语义,所以发明了C99中的div和ldiv以及lldiv,以便为有符号整数除法和余数运算提供明确指定的语义。
答案 1 :(得分:1)
C99标准说:
6.5.5乘法运算符
当整数被分割时, / 运算符的结果是任何代数商 分数部分丢弃 87)。如果商 a / b 可表示,则表达式为 (a / b)* b + a%b 应等于 a 。
87)这通常被称为''截断为零''
这意味着鸿沟总是向0舍入,所以你可以依赖它。
请注意,这与C ++ 03标准不同。
你的第二行是无符号除法,在除法之前将值-1
转换为unsigned int
。这总是小于2的幂,因此也很明确。
答案 2 :(得分:-3)
模运算符(%
)多年来一直是C和C ++标准的一部分。我不确定你可以在C ++中重载它。所以,你可以依靠它。