Compiling and running this code:
// List the range of the long double.
#include <stdio.h>
#include <float.h>
int main() {
printf("Long double: %Lg - %Lg\n", LDBL_MIN, LDBL_MAX);
}
Gives this result:
Long double: 3.3621e-4932 - 1.18973e 4932
Yet this code:
#include <stdio.h>
#include <float.h>
int main() {
long double ld = 1.18973e 4932;
printf("Longest double: %Lg", ld);
}
Gives this warning when compiled:
gcc -std=gnu99 -o fj -Wall -Wno-format-overflow -g r2.c -lm
r2.c:4:3: warning: floating constant exceeds range of ‘double’ [-Woverflow] 4 | long double ld = 1.18973e 4932; | ^~~~
However, if you compile
#include <stdio.h>
#include <float.h>
int main() {
long double ld = LDBL_MAX;
printf("Longest double: %Lg\n", ld);
}
It compiles and runs:
Longest double: 1.18973e 4932
What's going on here? It should accept the numerical limit that was listed in the first program, but it does just fine with the LDBL_MAX version of it.
My compiler: gcc --version
gcc (Debian 10.2.1-6) 10.2.1 20210110
My computer:
AMD Ryzen 5 5600G with Radeon Graphics CPU MHz: 3057.560 BogoMIPS: 7785.19 CPU cache size: 512 KB Debian GNU/Linux 11 (bullseye)
CodePudding user response:
1.18973e 4932
is an out-of-range double
constant.
LDBL_MAX
is an in range long double
constant.
Make the floating point constant a long double
by appending an L
.
Lower case l
is an option too, yet harder to distinguish from 1
.
// long double ld = 1.18973e 4932;
long double ld = 1.18973e 4932L; // Yet this is not quite the max
// max value better with adequate precision as
long double ld = 1.18973149535723176502e 4932L;
// Should print the same.
printf("Longest double: %.*Lg\n", LDBL_DECIMAL_DIG, ld);
printf("Longest double: %.*Lg\n", LDBL_DECIMAL_DIG, LDBL_MAX);
When coding near the limits, consider hex notation for better control in rounding issues.
long double ld = 1.1897315e 4932L; --> Infinity
long double ld = 1.18973149535723177e 4932L; --> Infinity
long double ld = 1.18973149535723176506e 4932L; --> Infinity
// 1.18973149535723176502e 4932L
long double ld = 0x1.fffffffffffffffep 16383L;