-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
This program
// g++ -std=c++11 -static -o m24_11 m24.cpp ; ./m24_11
int main()
{
long double t = 1;
printf("%.17Le\n", t / 100000);
}
outputs (Linux, expected result):
1.00000000000000000e-05
But in BashOnWindows, it outputs:
1.00000000000000008e-05
The long double data type in C/C++ under Linux using GCC for x86/x86-64 platform has an 80-bit format with 64 bits mantissa.
When a program using long double runs in BashOnWindows it behaves like having 53 bits mantissa number just like the usual "double" (but with almost the same exponential range as long double)
This harms functions like std::pow(long double, int) and hence boost::lexical_cast<double>(char*) (boost version 1.55) since internally it uses long double as intermediate result (but boost version 1.60 fixes this problem), therefore boost::program_options can reads double type options inaccurately also (even for exact input e.g. 0.03125 = 1/32).
Likewise this program:
// g++ -std=c++11 -static -o m25 m25.cpp ; ./m25
#include <stdio.h>
#include <limits>
int main()
{
long double t0, t1 = 1.0;
while (t1 > 0) {
t0 = t1;
t1 = t0 / 2;
}
long double lt = std::numeric_limits<long double>::denorm_min();
if (t0 == lt) {
printf("Good.\n");
} else {
printf("What? t0 = %.17Le != %.17Le\n", t0, lt);
}
}
Should output:
Good.
While in BashOnWindows, it output:
What? t0 = 7.46536864129530799e-4948 != 3.64519953188247460e-4951