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
This program
outputs (Linux, expected result):
1.00000000000000000e-05But in BashOnWindows, it outputs:
1.00000000000000008e-05The 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), thereforeboost::program_optionscan reads double type options inaccurately also (even for exact input e.g. 0.03125 = 1/32).Likewise this program:
Should output:
Good.While in BashOnWindows, it output:
What? t0 = 7.46536864129530799e-4948 != 3.64519953188247460e-4951