While using GMP to read floating point numbers, I noticed that when the
exponent is too large, the exponent overflows without warning or error.

GMP version: gmp-6.2.1-2.fc36.x86_64, installed using dnf on Fedora 36.
Test program: a.c and b.cpp, see attachment.
To run a.c, use "gcc a.c -o a -lgmp && ./a". The output on my machine
is "0.1e-3215911262793760767".
To run b.cpp, use "g++ b.cpp -o b -lgmp -lgmpxx && ./b". The output on
my machine is "1e+-1294967296".
The results are wrong because I entered a very large number, but got a
number between 0 and 1. I am expecting GMP to return an error in
mpf_init_set_str() indicating that the exponent is too large.

Thanks to https://stackoverflow.com/a/73740744, looks like the cause of
the bug it that GMP triggered a signed overflow in the following code
(from https://gmplib.org/repo/gmp/file/feb796a7f683/mpf/set_str.c#l315)
:

        while (dig < exp_base)
          {
            exp_in_base = exp_in_base * exp_base;
            exp_in_base += dig;
            c = (unsigned char) *expptr++;
            dig = digit_value[c];
          }

My gcc version information:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-
languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr --
mandir=/usr/share/man --infodir=/usr/share/info --with-
bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-
threads=posix --enable-checking=release --enable-multilib --with-
system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --
enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-
version-only --enable-libstdcxx-backtrace --with-linker-hash-style=gnu
--enable-plugin --enable-initfini-array --with-
isl=/builddir/build/BUILD/gcc-12.2.1-20220819/obj-x86_64-redhat-
linux/isl-install --enable-offload-targets=nvptx-none --without-cuda-
driver --enable-offload-defaulted --enable-gnu-indirect-function --
enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-
redhat-linux --with-build-config=bootstrap-lto --enable-link-
serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.1 20220819 (Red Hat 12.2.1-1) (GCC) 

My uname -a: Linux HOSTNAME 5.19.8-200.fc36.x86_64 #1 SMP
PREEMPT_DYNAMIC Thu Sep 8 19:02:21 UTC 2022 x86_64 x86_64 x86_64
GNU/Linux

/* gcc a.c -o a -lgmp && ./a */

#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");
}
// g++ b.cpp -o b -lgmp -lgmpxx && ./b

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

int main(void) {
    mpf_class f("1e3000000000");
    std::cout << f << std::endl;
}
_______________________________________________
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs

Reply via email to