比较双精度数和双精度文字?

发布于 2024-11-08 12:35:56 字数 388 浏览 4 评论 0原文

可能的重复:
我应该如何进行浮点比较?

不建议比较对于 C++ 中的 double 和 double 字面量来说相等,因为我猜它依赖于编译器?

更准确地说,比较硬编码的双精度数(源代码中的文字)和应该计算的双精度数是不行的,因为计算结果的最后一个数字可能因编译器而异。这不是标准化的吗?

我听说 Knuth 的 TeXbook 中提到了这一点,是吗?

如果这一切都是真的,解决方案是什么?

Possible Duplicate:
How should I do floating point comparison?

Is it not recommended to compare for equality a double and a double literal in C++, because I guess it is compiler dependent?

To be more precise it is not OK to compare a double which is hard-coded (a literal in the source code) and a double which should be computed, as the last number of the resultant of the calculation can vary from one compiler to another. Is this not standardized?

I heard this is mentioned in Knuth's TeXbook, is that right?

If this is all true, what is the solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼波传意 2024-11-15 12:35:56

你有点误解了这个建议。关键是浮点计算并不精确。出现舍入误差,精度逐渐丧失。以 1.0/10.0 这样简单的例子为例。结果应该0.1,但事实并非如此,因为0.1无法以浮点格式精确表示。所以实际结果会略有不同。对于无数其他操作也是如此,因此这一点与 const double 无关。这与不期望结果准确有关。如果您执行一些计算,结果应该1.0,那么您不应该测试它是否与1.0相等,因为舍入错误可能意味着它实际上是 0.9999999997

因此,通常的解决方案是测试结果是否足够接近 1.0。如果它很接近,那么我们假设“它足够好”,并表现得好像结果是 1.0。

最重要的是,严格相等很少用于浮点值。相反,您应该测试两个值之间的差异是否小于某个小值(通常称为 epsilon)

You've misunderstood the advice a bit. The point is that floating-point computations aren't exact. Rounding errors occur, and precision is gradually lost. Take something as simple as 1.0/10.0. The result should be 0.1, but it isn't, because 0.1 cannot be represented exactly in floating-point format. So the actual result will be slightly different. The same is true for countless other operations, so the point has nothing to do with const doubles. It has to do with not expecting the result to be exact. If you perform some computation where the result should be 1.0, then you should not test it for equality against 1.0, because rounding errors might mean that it actually came out 0.9999999997 instead.

So the usual solution is to test if the result is sufficiently close to 1.0. If it is close, then we assume "it's good enough", and act as if the result had been 1.0.

The bottom line is that strict equality is rarely used for floating-point values. Instead, you should test if the difference between the two values is less than some small value (typically called the epsilon)

忆悲凉 2024-11-15 12:35:56

您所讨论的问题是由于舍入误差造成的,并且每个浮点数都会发生这种情况。你可以做的是定义一个 epsilon 并看看两个浮点数之间的差异是否小于这个值。例如:

double A = somethingA();
double B = somethingB();

double epsilon = 0.00001;

if (abs(A - B) < epsilon)
  doublesAreEqual();

[编辑]另请参阅此问题:浮点数和双精度比较最有效的方法是什么?

The problem you are talking about is due to rounding errors and will happen for every floating point number. What you can do is define an epsilon and see if the difference between the two floating point numbers is smaller than this. E.g.:

double A = somethingA();
double B = somethingB();

double epsilon = 0.00001;

if (abs(A - B) < epsilon)
  doublesAreEqual();

[Edit] Also see this question: What is the most effective way for float and double comparison?.

开始看清了 2024-11-15 12:35:56

关键问题是浮点算术的工作原理 - 它包括舍入,可能会导致比较相等性评估错误。这适用于所有浮点数,无论变量是否声明为 const 。

The key problem is how floating point arithmetic works - it includes rounding that can lead to comparison for equality evaluated wrong. This applies to all floating point numbers regardless of whether variable is declared const or not.

年少掌心 2024-11-15 12:35:56

如果您进行浮点计算并且需要与某些固定值进行比较,那么使用 epsilon 值来考虑精度误差总是更安全。

示例:

double calcSomeStuf();

if ( calcSomeStuf() == 0.1 ) { ...}

是一个坏主意

,但是:

const double epsilon = 0.005

double calcSomeStuf();

if ( abs(calcSomeStuf() - 0.1) < epsilon ) { ...}

更安全(特别是考虑到 0.1 不能精确表示为双精度这一事实)

这是必要的,因为在累加浮点运算时会发生舍入错误,并且由于浮点的性质,并非所有错误都会发生数字可以准确表示

if you do floating point calculations and you need to do comparisons with certain fixed values it is always safer to use an epsilon value to take into account precision errors .

Example:

double calcSomeStuf();

if ( calcSomeStuf() == 0.1 ) { ...}

is a bad idea

however:

const double epsilon = 0.005

double calcSomeStuf();

if ( abs(calcSomeStuf() - 0.1) < epsilon ) { ...}

is a lot safer (especially considering the fact that 0.1 cannot be represented exactly as a double)

This is necessary because when accumulating floating point operations rounding errors occur, and due to the nature of floating point not all numbers can be represented exactly

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文