对于浮点数C++的模/模/余数运算(%或%%) ,是否有C或%%函数(或编译器标志),在角的情况下是否符合与Python或R中的等效函数/操作符相同的数学标准?
通常情况下,手术应该类似于
double modulus(x, y)
{
    return x - (y * floor(x / y));
}但是在许多情况下,这样简单的操作不会产生与Python和R相同的结果。
这些是Python和R中的一些示例,它们与fmod或remainder或上面的宏不匹配,即使在添加-frounding-math和-fsignaling-nans之后也是如此。
1 % (-1/3) = -1/3
1 % (-1/2) = 0
2 % Inf = 2
(-2) % Inf = Inf
2 % (-Inf) = -Inf
(-2) % (-Inf) = -2相反,fmod给出了:
1 % (-1/3) = 0
1 % (-1/2) = 0
2 % (Inf) = 2
-2 % (Inf) = -2
2 % (-Inf) = 2
-2 % (-Inf) = -2为了模拟结果,我想出了一些额外的条件:
double modulus(x, y)
{
    if (isinf(x)) {
        return NAN;
    }
    
    if (isinf(y)) {
        if (isinf(x))
            return NAN;
        else {
            if (x == 0 || isnan(x) || (x > 0) == (y > 0))
                return x;
            else
                return y;
        }
    }
    return x - (y * floor(x / y));
}但是即使这样,它仍然不能正确地适用于-1 < y < 0的情况,我甚至不知道我是否还缺少更多的角落案例。
我如何才能得到一个函数,在C/C++中给出与Python和R中的模运算符完全相同的结果?
发布于 2021-04-12 23:07:56
我没有找到Python所做的源代码,也没有找到NumPy源代码(它与Python匹配),据我所理解,它根据不同的类型调用SIMD指令,这很难读,但我设法找到了R源代码的模数。
最后,这并没有调用任何内置的C函数或组装指令,而且我怀疑它可能是在C99标准出现之前很久以前就从Cephes提取的。
/* Equivalences in order to work with C */
#define R_NaN NAN
#define c_eps DBL_EPSILON
#define R_FINITE(x) (!isinf(x))
typedef long double LDOUBLE;
#define _(msg) (msg)
#define warning(msg) (msg)
/* The actual code */
static double myfmod(double x1, double x2)
{
    if (x2 == 0.0) return R_NaN;
    if(fabs(x2) * c_eps > 1 && R_FINITE(x1) && fabs(x1) <= fabs(x2)) {
    return
        (fabs(x1) == fabs(x2)) ? 0 :
        ((x1 < 0 && x2 > 0) ||
         (x2 < 0 && x1 > 0))
         ? x1+x2  // differing signs
         : x1   ; // "same" signs (incl. 0)
    }
    double q = x1 / x2;
    if(R_FINITE(q) && (fabs(q) * c_eps > 1))
    warning(_("probable complete loss of accuracy in modulus"));
    LDOUBLE tmp = (LDOUBLE)x1 - floor(q) * (LDOUBLE)x2;
    return (double) (tmp - floorl(tmp/x2) * x2);
}摘自:https://github.com/wch/r-source/blob/trunk/src/main/arithmetic.c
发布于 2021-04-13 14:28:16
,我怎么能得到一个函数,在C/C++中给出与Python和R中的模运算符完全相同的结果?
这是一个奇怪的目标,因为目标通常是建立在客观标准的基础上的,而不是表现得像另一种语言,即使该语言没有很好的表现。
在任何情况下,C都有fmod(),这是OP考虑的一个余数函数。
没有指定数学函数来给出特定的答案。一个实现上的sin(x)可能与另一个实现的sin(x)不同,其目标是很好地匹配数学正弦(X)。如何做到这一点是一个质量的实现,而不是一个C规范。
一个好的fmod(x,y)可以被认为是。OP的modulus()存在着x - (y * floor(x / y));的不精确和范围问题
https://stackoverflow.com/questions/67065841
复制相似问题