首页 文章

计算gmp任意精度的机器精度

提问于
浏览
0

我正在尝试获取gmp变量的机器精度 .

为此,我调整了wikipedia的代码,以固定精度计算gmp的精度:

int main( int argc, char **argv )
{
    long int precision = 100;

mpf_set_default_prec(precision); // in principle redundant, but who cares

    mpf_t machEps, one, temp; // "one" is the "1" in gmp. tmp is to comparison.
    mpf_init2(machEps, precision); 
    mpf_set_ui(machEps, 1); // eps = 1
    mpf_init_set(one,machEps); // ensure "one" has the same precision as machEps
    mpf_init_set(temp,machEps); // ensure "temp" has the same precision as machEps

    do {
        mpf_div_ui(machEps,machEps,2); // eps = eps/2
        mpf_div_ui(temp,machEps,2);    // temp = eps/2
        mpf_add(temp,temp,one);        // temp += 1
    }
    while ( mpf_cmp(temp,one)); // temp == 1
    /// print the result...
    char *t = new char[400];
    mp_exp_t expprt;
    mpf_get_str(NULL, &expprt, 10, 10, machEps);

    sprintf(t, "%se%ld", mpf_get_str(NULL, &expprt, 10, mpf_get_default_prec(), machEps), expprt);

    printf( "Calculated Machine epsilon: %s\n", t);
    return 0;
}

但是,结果与维基百科的公式不一致,也没有随着我设置的精度而变化 . 我错过了什么?我也尝试过double和float(c标准),结果是正确的......

1 回答

  • 2

    我得到的结果与wikipedia's formula一致,值取决于精度 .

    但是,值 - 和有效精度 - 仅在越过肢体边界时发生变化(1) . 对我来说,这意味着64的倍数,所以

    (k-1)*64 < precision <= k*64
    

    计算出的机器epsilon是

    0.5^(k*64)
    

    一些结果:

    $ ./a.out 192
    Calculated Machine epsilon: 15930919111324522770288803977677118055911045551926187860739e-57
    $ ./a.out 193
    Calculated Machine epsilon: 8636168555094444625386351862800399571116000364436281385023703470168591803162427e-77
    

    为了比较:

    Prelude> 0.5^192
    1.5930919111324523e-58
    Prelude> 0.5^256
    8.636168555094445e-78
    

    GMP程序的输出格式为 mantissa,'e',exponent ,其中值为

    0.mantissa * 10^exponent
    

    (1)GMP将浮点数表示为一对指数(对于基数2)和尾数(和符号) . 尾数保持为无符号整数数组,即四肢 . 对我来说,四肢是64位,在32位系统上通常是32位(iirc) . 因此,当所需精度在 (k-1)*LIMB_BITS (不包括)和 k*LIMB_BITS (包括)之间时,尾数的数组包含 k 肢,并且所有这些都被使用,因此有效精度为 k*LIMB_BITS 位 . 因此,只有当肢体数量发生变化时,epsilon才会发生变化 .

相关问题