R&#39的R_pow()和libc的pow()之间的区别是什么?

时间:2014-07-02 20:05:56

标签: c r glibc rcpp pow

Writing R Extensions手册,Sec。 6.7.3。,声明声明为double R_pow (double x, double y)的R API函数计算x^y

  

[...]使用R_FINITE检查并返回适当的结果(与R相同)用于xy或i为0或缺失或无限或NaN的情况

但是,我找不到这样的xy,其中C库中的pow()函数会给出不正确的结果。我尝试了各种案例,例如xy being Inf , NA / NaN , integers, and so on, but I found no input data that generated the results different than those returned by ordinary pow()`。

Rcpp::evalCpp("::pow(1.124e-15, 2)", includes = "#include <cmath>") == Rcpp::evalCpp("R_pow(1.124e-15, 2)")
## [1] TRUE

也许你们会向我提供一些不正确的示例。

顺便说一句,我使用gcc 4.8.2和glibc 2.18(Fedora 20,x86_64)。 对于R_pow()源代码搜索R_pow here

1 个答案:

答案 0 :(得分:4)

查看我复制实际功能的source code可能最简单:

double R_pow(double x, double y) /* = x ^ y */
{
    /* squaring is the most common of the specially handled cases so
       check for it first. */
    if(y == 2.0)
        return x * x;
    if(x == 1. || y == 0.)
        return(1.);
    if(x == 0.) {
        if(y > 0.) return(0.);
        else if(y < 0) return(R_PosInf);
        else return(y); /* NA or NaN, we assert */
    }
    if (R_FINITE(x) && R_FINITE(y)) {
        /* There was a special case for y == 0.5 here, but
           gcc 4.3.0 -g -O2 mis-compiled it.  Showed up with
           100^0.5 as 3.162278, example(pbirthday) failed. */
        return pow(x, y);
    }
    if (ISNAN(x) || ISNAN(y))
        return(x + y);
    if(!R_FINITE(x)) {
        if(x > 0)               /* Inf ^ y */
            return (y < 0.)? 0. : R_PosInf;
        else {                  /* (-Inf) ^ y */
            if(R_FINITE(y) && y == floor(y)) /* (-Inf) ^ n */
                return (y < 0.) ? 0. : (myfmod(y, 2.) ? x  : -x);
        }
    }
    if(!R_FINITE(y)) {
        if(x >= 0) {
            if(y > 0)           /* y == +Inf */
                return (x >= 1) ? R_PosInf : 0.;
            else                /* y == -Inf */
                return (x < 1) ? R_PosInf : 0.;
        }
    }
    return R_NaN; // all other cases: (-Inf)^{+-Inf, non-int}; (neg)^{+-Inf}
}

显示在哪些情况下会崩溃到pow(x, y)