0

有人可以阐明这段代码的行为方式:

double x = 9223371036854;
int64_t y1 = /* trunc */ (x * 1000000);
int64_t y2 = round(x * 1000000);
cout << y1 << " <= " << y2 << endl;
assert( y1 <= y2 ); // fail

由于y1实际上等于9223371036854000000while y2is ,此代码失败9223371036853999616
取消注释后trunc一切正常(断言已验证)。

由 gcc-4.6.3-1ubuntu5 编译,带有g++ --std=c++0x x.cpp.

为什么int64_t(round(x * 1000000))小于int64_t(x * 1000000)哪里xdouble

为什么结果int64_t(trunc(x * 1000000))不同int64_t(x * 1000000)

4

1 回答 1

1

我想我找到了为什么它会这样工作(y1 == 92233710368540000000并且断言失败)。

GCC 优化了运行时计算,y1而不会丢失明显发生在y2. 更有趣的是文字的表达没有这样的属性

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

如果我将移出1e6表达式之外,一切都会按预期工作:

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

但可能我对优化的假设是不正确的。

于 2013-09-12T12:53:17.547 回答