C++中如何进行取模运算?

7

如何在C++中执行两个整数的模运算?


21
有没有一个术语来形容那些通过在谷歌搜索标题就可以得到答案的帖子? - msw
4
如果您不介意将Stack Overflow作为终极资源,即使是针对简单问题,那么请点击这里。 - Greg M. Krsak
6个回答

16

C++有%运算符,它被偶尔并且误导性地称为“模数”运算符。特别是STL在<functional>头文件中有modulus<>函数对象。请注意,这不是数学上的模运算符,因为在模算术中,对于任何值的a和任何正值的ba mod b按定义计算结果为非负值。在C++中,如果任意一个参数为负数,则a % b的结果符号是由实现定义的。因此,我们更适当地将%运算符命名为剩余运算符。

话虽如此,如果你真的想要数学上的模运算符,那么你可以定义一个函数来实现:

template<typename V>
V mod(const V& a, const V& b)
{
    return (a % b + b) % b;
}
只要 b 是正值,调用上述函数将产生非负结果。

4
其他人都没有提到在C++中,百分号实际上是一个取余运算符,并且无法提供一个正确地处理负数输入值的模数实现。这是最好的答案。 - leetNightshade
这是唯一正确的答案。如果你想要余数而不是模数,请使用%。 - undefined

14

10

正如其他答案所述,您可以使用C ++%操作符。 但要注意还有一个小细节:在表达式a%b中,如果a为负数,该操作的结果应该是正数还是负数? 这取决于C ++标准实现。 因此,如果您想可移植地处理负输入,您应该执行类似于r = abs(a)%b的操作,然后修复r的符号以匹配您的要求。


1
假设您希望隐含的 div 操作向零舍入。如果您想要向负无穷舍入,则需要使用 r = (unsigned(a) + offset * b) % b,其中 offset 要足够大,以使 a + offset * b 总是为正数。 - Mike DeSimone

9
像这样: x = y%z

4
负除数的结果为负数。 - Potatoswatter
3
@Potatocorn,也许是,也许不是。这取决于具体实现。 - wilhelmtell
1
@wilhelmtell: 5.6/4: “(a/b)*b + a%b is equal to a”, 所以向零舍入(无论好坏)意味着这一点,并且C++0x规定了它。 - Potatoswatter
1
C++0x规定了向零取整,但C++03没有。在这两个标准中,你的公式必须成立,但a%b的符号取决于整数除法的实现方式。只有当ab都是非负数时,该符号才被明确定义为非负数。 - Dennis Zickefoose
1
无论如何,它都不会将负整数映射到模算术环。如果它这样做了,你很幸运,但你的程序就非常不可移植。 - Potatoswatter
显示剩余2条评论

0

如果您使用双变量,应该使用“;”

double x;
double y;
double result = fmod(x, y);

0

使用取模运算符%

int modulus_a_b = a % b;

1
ab是整数...那么为什么要用doublemodulus_a_b应该与ab的类型相同。 - Mike DeSimone
@Mike:嗯,a%b将是int,或者与ab中至少一个的类型相同。因此,根据上下文,您可以选择modulus_a_b的类型。 :-) - Steve Jessop
@Steve:但是只有其中一种选择是%运算符返回的类型。其他所有选项都暗示着类型转换,也就是static_cast<>double显然是后者之一。此外,使用double意味着使用最慢的数学计算方式(除非有“long double”类型,那会很可怕)... - Mike DeSimone
我之所以说有很多选择,是因为例如 short % short 的结果是一个 int 而不是一个 short,但根据上下文,使用它作为 short 可能更有意义。因此,“与 a 和 b 相同的类型”与“避免隐式转换”之间存在冲突。 - Steve Jessop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接