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