【问题标题】:x*x != x*x in auto-variable?x*x != x*x 在自动变量中?
【发布时间】:2016-02-17 04:26:01
【问题描述】:

如何通过将x * x 存储在“auto 变量”中来更改它?我认为它应该仍然是相同的,我的测试表明类型、大小和值显然都相同的。

但即使x * x == (xx = x * x) 也是错误的。什么鬼?

(注意:我知道 IEEE 754 以及 float 和 double 如何工作以及它们常见的问题,但这让我感到困惑。)

#include <iostream>
#include <cmath>
#include <typeinfo>
#include <iomanip>
using namespace std;

int main() {
    auto x = sqrt(11);
    auto xx = x * x;
    cout << boolalpha << fixed << setprecision(130);
    cout << "   xx == 11           " << (   xx == 11          ) << endl;
    cout << "x * x == 11           " << (x * x == 11          ) << endl;
    cout << "x * x == xx           " << (x * x == xx          ) << endl;
    cout << "x * x == (xx = x * x) " << (x * x == (xx = x * x)) << endl;
    cout << "x * x == x * x        " << (x * x == x * x       ) << endl;
    cout << "types        " << typeid(xx).name() << " " << typeid(x * x).name() << endl;
    cout << "sizeofs      " << sizeof(xx) << " " << sizeof(x * x) << endl;
    cout << "xx           " << xx    << endl;
    cout << "x * x        " << x * x << endl;
}

这是输出:

   xx == 11           true
x * x == 11           false
x * x == xx           false
x * x == (xx = x * x) false
x * x == x * x        true
types        d d
sizeofs      8 8
xx           11.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
x * x        11.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

用这个编译:

C:\Stefan\code\leetcode>g++ test4.cpp -static-libstdc++ -std=c++11 -o a.exe

C:\Stefan\code\leetcode>g++ --version
g++ (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【问题讨论】:

  • 这与auto无关。你所有的变量都被推导出为doubles,这只是浮点精度的问题。参见例如this.
  • 不相关,但您可以使用std::cout&lt;&lt; std::boolalpha;bools 打印为truefalse。这将为您节省一些代码。
  • @juanchopanza 谢谢,现在用了。
  • @vsoftco 您的链接似乎没有解释这一点。真的吗?
  • @vsoftco 那里的问题完全不同,那里的答案都没有解释我的问题。看来你不明白我的问题。

标签: c++ variables floating-point


【解决方案1】:

这是双精度通常的不精确性。您没有提及您的硬件,但在 x86(32 位 Intel)上,计算期间使用的临时变量是 10 字节长的双精度数。 x * x 将是其中之一,而 xx = x * x 将存储为 8 字节双精度,然后再加载回 FPU 进行比较。

如果您打开优化或构建 64 位可执行文件,您可能会得到不同的结果。

【讨论】:

  • 有什么办法可以得到这样一个 10 字节长的 double 作为变量?
  • @StefanPochmann 将其声明为long double,但这取决于您的编译器支持什么。有些人会为long double 使用 10 个字节,其他人会使用 8 个字节。我不熟悉 g++ 来说明它的作用。
  • long double 工作,现在所有的比较都显示了我的预期(sizeof 是 12)。谢谢!
  • @StefanPochmann: long double 出于性能原因可能会对齐到 4 个字节。
  • 检查你的FLT_EVAL_METHOD
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多