浮法加成促进双重? [英] Float addition promoted to double?

查看:145
本文介绍了浮法加成促进双重?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天早上我有一个小的WTF时刻。 Ths WTF可以归纳为:

I had a small WTF moment this morning. Ths WTF can be summarized with this:

float x = 0.2f;
float y = 0.1f;
float z = x + y;
assert(z == x + y); //This assert is triggered! (Atleast with visual studio 2008)

原因似乎是表达式 x + y 被提升为double,并与 z 中的截断版本进行比较。 (如果我将 z 更改为 double ,则不会触发断言)。

The reason seems to be that the expression x + y is promoted to double and compared with the truncated version in z. (If i change z to double the assert isn't triggered).

我可以看到,出于精度原因,在将结果转换为单精度之前执行所有浮点运算符在双精度中是有意义的。我发现标准中的以下段落(我猜我已经知道,但不是在这种情况下):

I can see that for precision reasons it would make sense to perform all floating point arithmetics in double precision before converting the result to single precision. I found the following paragraph in the standard (which I guess I sort of already knew, but not in this context):

4.6.1。
类型 float 的右值可以转换为类型 double 的右值不变

4.6.1. "An rvalue of type float can be converted to an rvalue of type double. The value is unchanged"

我的问题是, x + y

UPDATE:由于许多人声称不应使用 ==

UPDATE: Since many people has claimed that one shouldn't use == for floating point, I just wanted to state that in the specific case I'm working with, an exact comparison is justified.

浮点比较是浮点数,因此我只想说明在我使用的特定情况下, / em>棘手,这里有一个有趣的链接,我认为没有提到。

Floating point comparision is tricky, here's an interesting link on the subject which I think hasn't been mentioned.

推荐答案

你不能一般假设 == 如预期的浮点类型。比较舍入值或使用 abs(a-b)公差

You can't generally assume that == will work as expected for floating point types. Compare rounded values or use constructs like abs(a-b) < tolerance instead.

升级完全由编译器决定(并且取决于目标硬件,优化级别等)。

Promotion is entirely at the compiler's discretion (and will depend on target hardware, optimisation level, etc).

在这种特殊情况下发生的事情几乎肯定是值以比内存高的精度存储在FPU寄存器中 - 通常,现代FPU硬件使用双精度或内部高精度,程序员要求的精度,编译器生成代码以在值存储到存储器时进行适当的转换;在未优化的构建中, x + y 的结果在进行比较的时候仍然在寄存器中,但 z 将被存储到内存并被取回,因此截断到浮点精度。

What's going on in this particular case is almost certainly that values are stored in FPU registers at a higher precision than in memory - in general, modern FPU hardware works with double or higher precision internally whatever precision the programmer asked for, with the compiler generating code to make the appropriate conversions when values are stored to memory; in an unoptimised build, the result of x+y is still in a register at the point the comparison is made but z will have been stored out to memory and fetched back, and thus truncated to float precision.

这篇关于浮法加成促进双重?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆