C++ 相当于 Java 的 Math.floorMod()?

问题描述 投票:0回答:3

在 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 条指令。

c++ modulo
3个回答
4
投票

嗯...

恐怕你得自己做一个。单行是一种自定义

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 |

1
投票

cmath头文件中的remainder()函数与math.floorMod()类似 对于整数运算

#include <cmath>
remainder(dividend, divisor)

余数函数可以重新创建如下

int floor_mod(int x, int y)
{   
   return  x-(x/y)*y  ;  
}

1
投票

虽然我不知道有任何内部函数能够执行此类操作,但我想修改提问者的实现以更好地模仿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;
    } ();
}

这里这个函数针对一些简单的输入进行了测试。

额外操作带来的开销似乎小于额外模数所需的开销(例如,参见那些快速基准测试:(1)(2))。

© www.soinside.com 2019 - 2024. All rights reserved.