我可以依赖C中的%(modulo)运算符来表示负数吗?

问题描述 投票:1回答:3

使用GCC:

printf("%i \n", -1 % (int)4);
printf("%u \n", -1 % (unsigned int)4);

输出:

-1
3

我可以跨平台依赖这种行为吗?我应该明确定义MODREM宏以确保不会改变吗?

c rounding modulo behavior floor-division
3个回答
4
投票

从C99起,%的结果需要被克里斯·多德引用为0。

在C99标准之前,%运算符对负数的行为是实现定义的。

当整数被划分并且除法不精确时,如果两个操作数都是正的,则/运算符的结果是小于代数商的最大整数,并且%运算符的结果是正的。如果任一操作数为负,则/运算符的结果是小于代数商的最大整数还是大于代数商的最小整数是实现定义的,这是%运算符的结果的符号。如果商a/b是可表示的,则表达式(a/b)*b + a%b应等于a

Does either ANSI C or ISO C specify what -5 % 10 should be?

因此,如果您的目标是C99或更新,结果为是,否则您不能依赖它。

如果你需要一致的结果和可移植性甚至更旧的C标准,你可以使用div or ldiv,无需定义自己的MODREM

C99 rationale regarding div, ldiv, and lldiv functions

因为当涉及负操作数时,C89具有用于划分有符号整数的实现定义语义,所以发明了C99中的div和ldiv以及lldiv,以便为有符号整数除法和余数运算提供明确指定的语义。


1
投票

C99标准说:

6.5.5乘法运算符

:

当整数被划分时,/运算符的结果是代数商,其中任何小数部分被丢弃87)。如果商a / b是可表示的,则表达式 (a / b)* b + a%b应等于a。

:

87)这通常被称为'截断为零''

这意味着鸿沟总是向0舍入,所以你可以依靠它。

请注意,这与C ++ 03标准不同。

你的第二行是无符号除法,在除法之前将值-1转换为unsigned int。这总是小于2的幂,因此也很明确。


-3
投票

模数运算符(%)多年来一直是C和C ++标准的一部分。我不确定你可以在C ++中重载它。所以,你可以依靠它。

© www.soinside.com 2019 - 2024. All rights reserved.