海湾合作委员会中特有的浮点数 [英] Peculiar floating point numbers in GCC

查看:60
本文介绍了海湾合作委员会中特有的浮点数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,对于浮点数,x * y == y * x,例如,可能不会持有
。但是,如果它是双方完全相同的操作怎么办?


我用GCC 3.4.4(Cygwin)测试了它,它打印0(编译用 -

g flag)


#include< cmath>

#include< iostream>


int main(){

double x = 3.0;


double f = std :: cos(x);

std :: cout<< (f == std :: cos(x))<< std :: endl;

}


使用-O3来优化某些东西,现在双方都是平等的。


VC ++ 8.0在调试和发布中打印1个。


标准有什么要说的?

解决方案

< n。************ @ gmail.comwrote in message

news:11 ******** *************@p77g2000hsh.googlegro ups.com ...


>我理解浮点数,x * y == y * x,例如,可能不会持有
。但是,如果它是双方完全相同的操作怎么办?


我用GCC 3.4.4(Cygwin)测试了它,它打印0(编译用 -

g flag)


#include< cmath>

#include< iostream>


int main(){

double x = 3.0;


double f = std :: cos(x);

std :: cout<< (f == std :: cos(x))<< std :: endl;

}


使用-O3来优化某些东西,现在双方都是平等的。


VC ++ 8.0在调试和发布中打印1个。


标准有什么要说的?



这不是真正的标准'我不会想到的问题,它只是

方式浮点数学工作。


在你的特殊情况下,这些语句是紧密相连的,初始化f b / b
和比较,所以编译器可能正在优化和比较相同的

的事情。这完全取决于编译器如何优化。甚至类似于:


double f = std :: cos(x);

double g = std :: cos(x);

std :: cout<< (f == g)<< std :: endl;


可能会输出1或0,具体取决于编译器的优化。


你不能指望浮点相等,它有时可能会工作,而不是

其他人。


Jim Langston写道:


>

这不是真正的标准'我不会想到的问题,它只是浮​​点数学运作的方式。



不要偏执。 < g这是这种差异的具体原因。


在您的特定情况下,这些陈述是紧密相连的,初始化为
和比较,所以编译器可能正在优化和比较相同的

的事情。这完全取决于编译器如何优化。甚至类似于:


double f = std :: cos(x);

double g = std :: cos(x);

std :: cout<< (f == g)<< std :: endl;


可能会输出1或0,具体取决于编译器的优化。



它有更好的输出1,无论编译器优化如何。


你不能指望浮点数相等,它有时可能会工作,而不是

其他人。



这里不那么微妙的问题是允许编译器以比类型要求更高的精度执行
浮点运算。在

x86这意味着浮点数学用80位值完成,

而float是32位而double是64位。 (允许

这是速度的原因:x86 80位浮点数学比64位快得多

math)当你存入一个double时,但是,存储的值必须具有

的正确精度。因此将cos的结果存储在double中可以强制截断一个宽于double的值。将存储的

值与原始值进行比较时,编译器会将原始值扩展到80



但是,在您的示例中,两个结果都已存储,因此当扩展时它们

应该产生相同的结果。但是,有些编译器不会这样做,除非你告诉他们必须遵守规则(速度再次提高),否则不会这样做。


-


- Pete

Roundhouse Consulting,Ltd。( www.versatilecoding.com

标准C ++库扩展:教程和
参考的作者。 ( www.petebecker.com/tr1book

< br>

" Pete Becker" < pe ** @ versatilecoding.com写信息

新闻:xv **************************** **@giganews.com ...


Jim Langston写道:


>> <这不是真正的标准'我不会想到的问题,它只是浮​​点数学的工作方式。


不要偏执。 < g这是这种差异的具体原因。


>在您的特定情况下,这些陈述是紧密相连的,
初始化f和比较,所以编译器可能正在优化和比较同样的事情。这完全取决于编译器如何优化。
甚至类似于:

double f = std :: cos(x);
double g = std :: cos(x) ;
std :: cout<< (f == g)<< std :: endl;

可能输出1或0,具体取决于编译器优化。



无论编译器优化如何,它都有更好的输出1 。


>你不能指望浮点平等,它有时可能会起作用,而不是其他人。



这里不那么微妙的问题是允许编译器以高于类型的精度执行
浮点运算需要。在

x86这意味着浮点数学用80位值完成,

而float是32位而double是64位。 (允许

这是速度的原因:x86 80位浮点数学比64位快得多

math)当你存入一个double时,但是,存储的值必须具有正确的
精度。因此将cos的结果存储在double中会强制截断一个宽于double的值。将存储值

与原始值进行比较时,编译器将原始值扩展为80位,并且

结果与原始值不同。这就是原始示例中发生的事情




但是在你的例子中,两个结果都存储了,所以当它们加宽时它们

应该产生相同的结果。但是,有些编译器不会这样做,除非你告诉他们必须遵守规则(速度再次提高),否则你需要b $ b。



FAQ 29.18不同意你的意见。

http://www.parashift.com/c++-faq-lit...html#faq-29.18


I understand that with floats, x*y == y*x, for example, might not
hold. But what if it''s the exact same operation on both sides?

I tested this with GCC 3.4.4 (Cygwin), and it prints 0 (compiled with -
g flag)

#include <cmath>
#include <iostream>

int main() {
double x = 3.0;

double f = std::cos(x);
std::cout << (f == std::cos(x)) << std::endl;
}

Using -O3 instead optimizes something, and now both sides are equal.

VC++8.0 prints 1 in both debug and release.

What does the standard have to say?

解决方案

<n.************@gmail.comwrote in message
news:11*********************@p77g2000hsh.googlegro ups.com...

>I understand that with floats, x*y == y*x, for example, might not
hold. But what if it''s the exact same operation on both sides?

I tested this with GCC 3.4.4 (Cygwin), and it prints 0 (compiled with -
g flag)

#include <cmath>
#include <iostream>

int main() {
double x = 3.0;

double f = std::cos(x);
std::cout << (f == std::cos(x)) << std::endl;
}

Using -O3 instead optimizes something, and now both sides are equal.

VC++8.0 prints 1 in both debug and release.

What does the standard have to say?

It''s not really the standard that''s the issue I dont'' think, it''s just the
way floating point math works.

In your particular case, those statements are close together, initializing f
and the comparison, so the compiler may be optimizing and comparing the same
thing. It all depends on how the compiler optimizes. Even something like:

double f = std::cos(x);
double g = std::cos(x);
std::cout << ( f == g ) << std::endl;

may output 1 or 0, depending on compiler optimization.

You just cant count on floating point equality, it may work sometimes, not
others.


Jim Langston wrote:

>
It''s not really the standard that''s the issue I dont'' think, it''s just the
way floating point math works.

Don''t get paranoid. <gThere''s a specific reason for this descrepancy.

In your particular case, those statements are close together, initializing f
and the comparison, so the compiler may be optimizing and comparing the same
thing. It all depends on how the compiler optimizes. Even something like:

double f = std::cos(x);
double g = std::cos(x);
std::cout << ( f == g ) << std::endl;

may output 1 or 0, depending on compiler optimization.

It had better output 1, regardless of compiler optimizations.

You just cant count on floating point equality, it may work sometimes, not
others.

The not-so-subtle issue here is that the compiler is permitted to do
floating-point arithmetic at higher precision than the type requires. On
the x86 this means that floating-point math is done with 80-bit values,
while float is 32 bits and double is 64 bits. (The reason for allowing
this is speed: x86 80-bit floating-point math is much faster than 64-bit
math) When you store into a double, the stored value has to have the
right precision, though. So storing the result of cos in a double can
force truncation of a wider-than-double value. When comparing the stored
value to the original one, the compiler widens the original out to 80
bits, and the result is different from the original value. That''s what''s
happening in the original example.

In your example, though, both results are stored, so when widened they
should produce the same result. Some compilers don''t do this, though,
unless you tell them that they have to obey the rules (speed again).

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)


"Pete Becker" <pe**@versatilecoding.comwrote in message
news:xv******************************@giganews.com ...

Jim Langston wrote:

>>
It''s not really the standard that''s the issue I dont'' think, it''s just
the way floating point math works.


Don''t get paranoid. <gThere''s a specific reason for this descrepancy.

>In your particular case, those statements are close together,
initializing f and the comparison, so the compiler may be optimizing and
comparing the same thing. It all depends on how the compiler optimizes.
Even something like:

double f = std::cos(x);
double g = std::cos(x);
std::cout << ( f == g ) << std::endl;

may output 1 or 0, depending on compiler optimization.


It had better output 1, regardless of compiler optimizations.

>You just cant count on floating point equality, it may work sometimes,
not others.


The not-so-subtle issue here is that the compiler is permitted to do
floating-point arithmetic at higher precision than the type requires. On
the x86 this means that floating-point math is done with 80-bit values,
while float is 32 bits and double is 64 bits. (The reason for allowing
this is speed: x86 80-bit floating-point math is much faster than 64-bit
math) When you store into a double, the stored value has to have the right
precision, though. So storing the result of cos in a double can force
truncation of a wider-than-double value. When comparing the stored value
to the original one, the compiler widens the original out to 80 bits, and
the result is different from the original value. That''s what''s happening
in the original example.

In your example, though, both results are stored, so when widened they
should produce the same result. Some compilers don''t do this, though,
unless you tell them that they have to obey the rules (speed again).

FAQ 29.18 disagrees with you.

http://www.parashift.com/c++-faq-lit...html#faq-29.18


这篇关于海湾合作委员会中特有的浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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