【发布时间】:2014-09-27 21:37:52
【问题描述】:
我尝试使用 C++ 的 % 运算符得到 -1 模 1000000007 的结果
和fmod 函数。
输出是-1,但是-1 modulo 1000000007==1000000006。
我做错了什么?
【问题讨论】:
我尝试使用 C++ 的 % 运算符得到 -1 模 1000000007 的结果
和fmod 函数。
输出是-1,但是-1 modulo 1000000007==1000000006。
我做错了什么?
【问题讨论】:
说白了,你选错了运算符。
C++ 和 C % 不是模数,而是余数。
assert(a / b * b + a % b == a); // for integral types
如果a 为非负数,则模数和余数相同。
否则返回值为负,加b即可。
template<class T>
inline constexpr auto
modulo(T a, T b) -> decltype(a%b) {
auto r = a % b;
if (r < 0) r += b;
return r;
}
或者(也)对于 C:
#define modulo(a, b) (a % b < 0 ? a % b + b : a % b)
为了完整性:在 C++11 之前,a / b 可以始终向下舍入而不是始终为 0,尽管 C++03 已经注意到下一个标准可能会要求舍入为 0。
模是欧几里得除法的余数,并且总是在范围 0
在数学中,余数是执行一些计算后“剩余”的数量。
【讨论】:
a/b 有一个相应的定义,当% 执行您调用的模数运算时,a/b * b + a%b == a 成立。在 C++11 之前,a/b 和 a%b 的具体定义是实现定义的。 C++11 现在指定除法提供向零截断的代数商,这排除了 % 是您调用的模运算。
a < 0 && b < 0,建议if (r<0) { m = r < 0 ? m - r : m + r; }而不是if(r<0) r += b;
处理负除数和正除数的模函数:
template<class T>
inline constexpr auto
modulo(T a, T b) -> decltype(a%b) {
auto r = a % b;
if((b > 0 && r < 0) || (b < 0 && r > 0))
r += b;
return r;
}
【讨论】: