Could someone shed a light on the way this code behaves:
double x = 9223371036854;
int64_t y1 = /* trunc */ (x * 1000000);
int64_t y2 = round(x * 1000000);
cout << y1 << " <= " << y2 << endl;
assert( y1 <= y2 ); // fail
This code fails due to y1
actually equals to 9223371036854000000
while y2
is 9223371036853999616
.
After uncommenting trunc
everything is ok (assertion verified).
Compiled by gcc-4.6.3-1ubuntu5 with g++ --std=c++0x x.cpp
.
Why int64_t(round(x * 1000000))
is less than int64_t(x * 1000000)
where x
is double
?
And why results of int64_t(trunc(x * 1000000))
is different from int64_t(x * 1000000)
?
I guess I found why it works like this ( y1 == 92233710368540000000
and assert fails).
GCC optimized out run-time calculation of y1
without loosing precision which clearly happens in y2
. More intersting is that expression of literals have no such property
double x = 9223371036854;
int64_t y1 = /* trunc */ (x * 1000000);
int64_t y2 = round(x * 1000000);
cout << y1 << " <= " << y2 << endl;
assert( int64_t(9223371036854.0 * 1000000) <= int64_t(round(9223371036854e6)) ); // ok
assert( int64_t(x * 1000000) <= int64_t(round(x * 1000000)) ); // fails
assert( y1 <= y2 ); // fails
And if I'll move out 1e6
outside of expressions everything works as expected:
double x = 9223371036854.0 * 1000000;
int64_t y1 = /* trunc */ (x);
int64_t y2 = round(x);
cout << y1 << " <= " << y2 << endl;
assert( int64_t(x) <= int64_t(round(x)) ); // ok
assert( y1 <= y2 ); // ok
But probably my assumption about optimization is incorrect.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.