【问题标题】:GMP detect float exponent overflow when initializingGMP 在初始化时检测浮点指数溢出
【发布时间】:2022-09-30 17:47:26
【问题描述】:

我目前正在 64 位 Fedora 36 上编程,我意识到 GMP 浮点数对指数大小有限制:https://gmplib.org/manual/Floating_002dpoint-Functions

每个浮点数的指数具有固定精度,在大多数系统上是一个机器字。在当前实现中,指数是肢体的数量,因此例如在 32 位系统上,这意味着大约 2^-68719476768 到 2^68719476736 的范围,或者在 64 位系统上,这将更大

例如,下面的 C 程序在我的机器上打印 0.1e-3215911262793760767

#include <assert.h>
#include <stdio.h>
#include <gmp.h>

int main(void) {
    mpf_t f;
    const char *s = \"1e3000000000000000000000000000000\";
    assert(mpf_init_set_str(f, s, 10) == 0);
    assert(mpf_out_str(NULL, 10, 100, f));
    printf(\"\\n\");
}

使用 C++ 接口时也会出现此问题。以下 C++ 程序输出 1e+-1294967296

#include <iostream>
#include <gmpxx.h>

int main(void) {
    mpf_class f(\"1e3000000000\");
    std::cout << f << std::endl;
}

有没有办法检测指数溢出?例如,我期望mpf_init_set_str() 返回一个非零值来指示错误。或者,在初始化 mpf_class f 时可能会引发 C++ 异常。但是,目前浮点数已成功初始化为错误的值。否则,这是 GMP 中的错误吗?

  • 我想知道这样的输入是从哪里来的,但是是的,只有 GMP 才能捕获它。
  • 不是答案,但您应该将 MPFR 用于新代码,GMP 主要将 mpf_t 保留为旧代码。

标签: c++ gmp


【解决方案1】:

是的,这是一个 GMP 错误。举报!当前的实现可能导致未定义的行为,甚至是分段错误。你可以在this 看到。

【讨论】:

    【解决方案2】:

    这不是错误。这记录在 GMP 手册中:

    “mpf”函数和变量没有无穷大或非数字的特殊概念,应用程序必须注意不要溢出指数,否则结果将不可预测。

    基本上,mpf 号码上的溢出是未定义的行为。如果你想要明确定义的行为,你应该使用GNU MPFR

    【讨论】:

      最近更新 更多