在 Java 中,我们有两种不同的模(和余数)运算,
%
和 Math.floorMod()
。区别在于映射目标的区域,它可以取决于第一个操作数的符号或第二个操作数的符号。 此页面很好地解释了差异。
C++ 中是否存在与
Math.floorMod()
效果相同的等效(快速)操作?
我目前采用以下方法(出于性能原因,它甚至不完全等同于
Math.floorMod()
):
inline int floor_mod(int x, int y) {
x %= y;
if (x < 0) {
x += y;
}
return x;
}
我认为可能存在一个内在的或类似的东西,在某些 CPU 上只能编译为 1 条指令。
嗯...
恐怕你得自己做一个。单行是一种自定义
floorModulo
,但是如果您期望 unsigned int&
作为除数,则一个 if 测试可能会更快(并且更具可读性)。
#include <iostream>
int myCustomModulo(const int& a, const int& b);
int main()
{
std::cout
<< "| mod & +divisor | mod & -divisor |\n"
<< "| :------------- | -------------- |\n"
;
int b{ 3 };
for (int a{ -5 }; a < 0; ++a)
std::cout
<< "| " << a << " mod " << b << " = " << myCustomModulo(a, b) << " "
<< "| " << a << " mod " << -b << " = " << myCustomModulo(a, -b) << " |"
<< std::endl
;
for (int a{ 0 }; a < 6; ++a)
std::cout
<< "| " << a << " mod " << b << " = " << myCustomModulo(a, b) << " "
<< "| " << a << " mod " << -b << " = " << myCustomModulo(a, -b) << " |"
<< std::endl
;
}
int myCustomModulo(const int& a, const int& b)
{
return (a % b + b) % b;
}
输出:
| mod & +divisor | mod & -divisor |
| :------------- | -------------- |
| -5 mod 3 = 1 | -5 mod -3 = -2 |
| -4 mod 3 = 2 | -4 mod -3 = -1 |
| -3 mod 3 = 0 | -3 mod -3 = 0 |
| -2 mod 3 = 1 | -2 mod -3 = -2 |
| -1 mod 3 = 2 | -1 mod -3 = -1 |
| 0 mod 3 = 0 | 0 mod -3 = 0 |
| 1 mod 3 = 1 | 1 mod -3 = -2 |
| 2 mod 3 = 2 | 2 mod -3 = -1 |
| 3 mod 3 = 0 | 3 mod -3 = 0 |
| 4 mod 3 = 1 | 4 mod -3 = -2 |
| 5 mod 3 = 2 | 5 mod -3 = -1 |
您的链接的正确结果:
| mod & +divisor | mod & -divisor |
| :------------- | :--------------|
| -5 mod 3 = 1 | -5 mod -3 = -2 |
| -4 mod 3 = 2 | -4 mod -3 = -1 |
| -3 mod 3 = 0 | -3 mod -3 = 0 |
| -2 mod 3 = 1 | -2 mod -3 = -2 |
| -1 mod 3 = 2 | -1 mod -3 = -1 |
| 0 mod 3 = 0 | 0 mod -3 = 0 |
| 1 mod 3 = 1 | 1 mod -3 = -2 |
| 2 mod 3 = 2 | 2 mod -3 = -1 |
| 3 mod 3 = 0 | 3 mod -3 = 0 |
| 4 mod 3 = 1 | 4 mod -3 = -2 |
| 5 mod 3 = 2 | 5 mod -3 = -1 |
cmath头文件中的remainder()函数与math.floorMod()类似 对于整数运算
#include <cmath>
remainder(dividend, divisor)
余数函数可以重新创建如下
int floor_mod(int x, int y)
{
return x-(x/y)*y ;
}
虽然我不知道有任何内部函数能够执行此类操作,但我想修改提问者的实现以更好地模仿Java函数
Math.floorMod(dividend,divisor)
constexpr int floor_mod(int dividend, int divisor)
{
return [divisor, remainder = dividend % divisor] {
return remainder && (remainder < 0 != divisor < 0)
? remainder + divisor
: remainder;
} ();
}
这里这个函数针对一些简单的输入进行了测试。