Reputation: 1562
I am currently programming on 64-bit Fedora 36, and I realized that GMP floating point numbers have limitations on the exponent size: https://gmplib.org/manual/Floating_002dpoint-Functions
The exponent of each float has fixed precision, one machine word on most systems. In the current implementation the exponent is a count of limbs, so for example on a 32-bit system this means a range of roughly 2^-68719476768 to 2^68719476736, or on a 64-bit system this will be much greater
For example, the following C program prints 0.1e-3215911262793760767
on my machine.
#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");
}
This problem also happens when using the C++ interface. The following C++ program outputs 1e+-1294967296
:
#include <iostream>
#include <gmpxx.h>
int main(void) {
mpf_class f("1e3000000000");
std::cout << f << std::endl;
}
Is there a way to detect the exponent overflow? For example, I am expecting mpf_init_set_str()
to return a non-zero value to indicate the error. Or a C++ exception can be raised while initializing mpf_class f
. However, currently the floats initialize successfully to the wrong value. Otherwise, is this a bug in GMP?
Upvotes: 4
Views: 126
Reputation: 3476
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.
Basically, overflow on mpf numbers is undefined behavior. If you want well-defined behavior, you should use GNU MPFR instead.
Upvotes: 1