具有MPFR的不同精度的亚正规数



我想模拟各种n位二进制浮点格式,每种格式都有指定的e_maxe_min,精度为p。我希望这些格式能够模拟低于标准的数字,忠实于IEEE-754标准。

当然,我的搜索让我找到了MPFR库,它符合IEEE-754,并且能够支持具有mpfr_subnormalize()函数的子规范。然而,我在使用mpfr_set_emin()mpfr_set_emax()来正确设置一个支持亚正常的环境时遇到了一些困惑。我将使用IEEE双精度作为示例格式,因为这是MPFR手册中使用的示例:

http://mpfr.loria.fr/mpfr-current/mpfr.html#index-mpfr_005fsubnormalize

mpfr_set_default_prec (53);
mpfr_set_emin (-1073); mpfr_set_emax (1024);

上面的代码来自上面链接中的MPFR手册-请注意,e_maxe_min都不等于double的预期值。这里,p被设置为53,正如double类型所期望的那样,但是e_max设置为1024,而不是正确的值1023,并且e_min设定为-1073;远低于-1022的正确值。我知道,在MPFR的中间计算中,将指数边界设置得太紧会导致上溢/下溢,但我发现,准确设置e_min对于确保正确的次正规数至关重要;过高或过低导致低于正常的MPFR结果(用mprf_subnormalize()更新)与对应的double结果不同。

我的问题是,应该如何决定将哪些值传递给mpfr_set_emax()和(尤其是)mpfr_set_emin(),以确保具有指数边界e_maxe_min的浮点格式的正确亚正常行为?似乎没有任何关于此事的详细文件或讨论。

感谢

詹姆斯。

2016年7月30日编辑:这是一个小程序,演示了单精度数字的e_maxe_min选择。

#include <iostream>
#include <cmath>
#include <float.h>
#include <mpfr.h>
using namespace std;
int main (int argc, char *argv[]) {
    cout.precision(120);
    // IEEE-754 float emin and emax values don't work at all
    //mpfr_set_emin (-126);
    //mpfr_set_emax (127);
    // Not quite
    //mpfr_set_emin (-147);
    //mpfr_set_emax (128);
    // Not quite
    //mpfr_set_emin (-149);
    //mpfr_set_emax (128);
    // These float emin and emax values work in subnormal range
    mpfr_set_emin (-148);
    mpfr_set_emax (128);
    cout << "emin: " << mpfr_get_emin() << "    emax: " << mpfr_get_emax() << endl;
    float f = FLT_MIN;
    for (int i = 0; i < 3; i++) f = nextafterf(f, INFINITY);
    mpfr_t m;
    mpfr_init2 (m, 24);
    mpfr_set_flt (m, f, MPFR_RNDN);
    for (int i = 0; i < 6; i++) {
        f = nextafterf(f, 0);
        mpfr_nextbelow(m);
        cout << i << ": float: " << f << endl;
        //cout << i << ":  mpfr: " << mpfr_get_flt (m, MPFR_RNDN) << endl;
        mpfr_subnormalize (m, 1, MPFR_RNDN);
        cout << i << ":  mpfr: " << mpfr_get_flt (m, MPFR_RNDN) << endl;
    }
    mpfr_clear (m);
    return 0;
}

我正在复制我在ResearchGate上给出的答案(带有指向mpfr_subnormalize文档的链接):

有不同的约定来表示有效位和相关的指数。IEEE 754选择考虑1和2之间的有效位,而MPFR(与C语言一样,例如参见DBL_MAX_EXP)选择考虑1/2和1之间的有效位数(出于与多精度相关的实际原因)。例如,数字17在IEEE 754中表示为1.0001·24,在MPFR中表示为0.10001·25。正如您所看到的,这意味着与IEEE 754相比,MPFR中的指数增加了1,因此emax=1024,而不是1023,以实现双倍精度。

关于双精度的emin的选择,需要能够表示2−1074=0.1·2−1073,因此emin至多需要−1073(如在MPFR中,所有数字都被归一化)。

如文献所述,mpfr_subnormalize函数认为亚正态指数范围从emin到emin+PREC(x)−1,因此,例如,您需要设置emin=−1073来模拟IEEE双精度。

相关内容

  • 没有找到相关文章

最新更新