如何在C++中执行两个整数的模运算?
C++有%
运算符,它被偶尔并且误导性地称为“模数”运算符。特别是STL在<functional>
头文件中有modulus<>
函数对象。请注意,这不是数学上的模运算符,因为在模算术中,对于任何值的a
和任何正值的b
,a mod b
按定义计算结果为非负值。在C++中,如果任意一个参数为负数,则a % b
的结果符号是由实现定义的。因此,我们更适当地将%
运算符命名为剩余运算符。
话虽如此,如果你真的想要数学上的模运算符,那么你可以定义一个函数来实现:
template<typename V>
V mod(const V& a, const V& b)
{
return (a % b + b) % b;
}
只要 b
是正值,调用上述函数将产生非负结果。正如其他答案所述,您可以使用C ++%操作符。 但要注意还有一个小细节:在表达式a%b
中,如果a
为负数,该操作的结果应该是正数还是负数?
这取决于C ++标准实现。 因此,如果您想可移植地处理负输入,您应该执行类似于r = abs(a)%b
的操作,然后修复r
的符号以匹配您的要求。
div
操作向零舍入。如果您想要向负无穷舍入,则需要使用 r = (unsigned(a) + offset * b) % b
,其中 offset
要足够大,以使 a + offset * b
总是为正数。 - Mike DeSimonea%b
的符号取决于整数除法的实现方式。只有当a
和b
都是非负数时,该符号才被明确定义为非负数。 - Dennis Zickefoose如果您使用双变量,应该使用“;”
double x;
double y;
double result = fmod(x, y);
使用取模运算符%
:
int modulus_a_b = a % b;
a
和b
是整数...那么为什么要用double
?modulus_a_b
应该与a
和b
的类型相同。 - Mike DeSimonea%b
将是int
,或者与a
和b
中至少一个的类型相同。因此,根据上下文,您可以选择modulus_a_b
的类型。 :-) - Steve Jessop%
运算符返回的类型。其他所有选项都暗示着类型转换,也就是static_cast<>
。double
显然是后者之一。此外,使用double
意味着使用最慢的数学计算方式(除非有“long double”类型,那会很可怕)... - Mike DeSimoneshort % short
的结果是一个 int
而不是一个 short
,但根据上下文,使用它作为 short
可能更有意义。因此,“与 a 和 b 相同的类型”与“避免隐式转换”之间存在冲突。 - Steve Jessop