首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C中匹配Python模/余数

在C中匹配Python模/余数
EN

Stack Overflow用户
提问于 2021-04-12 21:21:43
回答 2查看 191关注 0票数 0

对于浮点数C++的模/模/余数运算(%%%) ,是否有C或%%函数(或编译器标志),在角的情况下是否符合与Python或R中的等效函数/操作符相同的数学标准?

通常情况下,手术应该类似于

代码语言:javascript
运行
复制
double modulus(x, y)
{
    return x - (y * floor(x / y));
}

但是在许多情况下,这样简单的操作不会产生与Python和R相同的结果。

这些是Python和R中的一些示例,它们与fmodremainder或上面的宏不匹配,即使在添加-frounding-math-fsignaling-nans之后也是如此。

代码语言:javascript
运行
复制
1 % (-1/3) = -1/3
1 % (-1/2) = 0
2 % Inf = 2
(-2) % Inf = Inf
2 % (-Inf) = -Inf
(-2) % (-Inf) = -2

相反,fmod给出了:

代码语言:javascript
运行
复制
1 % (-1/3) = 0
1 % (-1/2) = 0
2 % (Inf) = 2
-2 % (Inf) = -2
2 % (-Inf) = 2
-2 % (-Inf) = -2

为了模拟结果,我想出了一些额外的条件:

代码语言:javascript
运行
复制
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中的模运算符完全相同的结果?

EN

Stack Overflow用户

发布于 2021-04-12 23:07:56

我没有找到Python所做的源代码,也没有找到NumPy源代码(它与Python匹配),据我所理解,它根据不同的类型调用SIMD指令,这很难读,但我设法找到了R源代码的模数。

最后,这并没有调用任何内置的C函数或组装指令,而且我怀疑它可能是在C99标准出现之前很久以前就从Cephes提取的。

代码语言:javascript
运行
复制
/* 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

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67065841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档