Re: GMP does not detect float exponent overflow while reading floating point numbers

2022-09-30 Thread Vincent Lefevre
On 2022-09-16 16:34:58 -0400, Eric Li wrote:
> 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)
[...]

I've given an answer:

  https://stackoverflow.com/a/73906883/3782797

This is not a bug. This is documented in the GMP manual:

  The 'mpf' functions and variables have no special notion of infinity
  or not-a-number, and applications must take care not to overflow the
  exponent or results will be unpredictable.

As Paul said, you should use GNU MPFR if you want well-defined
behavior.

-- 
Vincent Lefèvre  - Web: 
100% accessible validated (X)HTML - Blog: 
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: GMP does not detect float exponent overflow while reading floating point numbers

2022-09-29 Thread Paul Zimmermann
   Hi Eric,


> 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.

on gmplib.org you can read:

High-level floating-point arithmetic functions (mpf). This is the GMP function 
category to use if the C type `double' doesn't give enough precision for an 
application. There are about 70 functions in this category. New projects should 
strongly consider using the much more complete GMP extension library mpfr 
instead of mpf.

Indeed with the following MPFR program you will get:

$ gcc -g /tmp/b.c -lmpfr
$ ./a.out
@Inf@

$ cat /tmp/b.c
#include 
#include 
#include 

int main(void) {
mpfr_t f;
const char *s = "1e300";
mpfr_init_set_str(f, s, 10, MPFR_RNDN);
mpfr_out_str (stdout, 10, 100, f, MPFR_RNDN);
printf("\n");
}

Hope this helps,
Paul
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


GMP does not detect float exponent overflow while reading floating point numbers

2022-09-29 Thread Eric Li
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 
#include 
#include 

int main(void) {
mpf_t f;
const char *s = "1e300";
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 
#include 

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