2014-09-27 94 views

回答

8

说白了,你拿错了算子。

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

Wikipedia on modulo

模是euclidiean除法的余数,并总是在范围0 < =模<除数

+1

有一个/ B'使得'A/B * B + A%B的'对应的定义==''在'%'确实执行你正在调用的模的操作时成立。在C++ 11之前,“a/b”和“a%b”的具体定义是实现定义的。 C++ 11现在指定除法提供的代数商被截断为零,这就排除了'%'是您要调用的模的操作。 – bames53 2014-09-27 21:49:09

+0

现在我明白了区别。你可以在C++ – 2014-09-27 21:52:16

+0

中展示模的一个示例用法。为了处理'a <0 && b <0',建议'if(r <0){m = r <0? m - r:m + r; }'而不是'if(r <0)r + = b;' – chux 2014-09-27 23:29:18

0

模函数来处理负除数以及正除数:

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; 
}