2009-11-07 104 views
3

昨天我问了一个浮点问题,我又有一个问题。我正在做一些计算,我使用math.h(C语言)的正弦,余弦和正切函数的结果。浮点再次

其中一位开发者嘀咕道,你必须小心这些函数的返回值,我不应该对gcc数学函数的返回值做出假设。我不想开始讨论,但我真的很想知道在使用标准数学函数进行计算时需要注意什么。

X

+1

您已经成功创建了两个帐户。您之前的问题是使用http://stackoverflow.com/users/205441/xofo问的。电子邮件[email protected]关于让他们合并。 – ChrisF 2009-11-07 21:54:30

+0

不完全回答你的问题,但如果你使用gcc,你可以尝试使用-mfpmath = sse标志来减少一些浮点错误。 – int3 2009-11-08 10:23:36

回答

3

你不应该假定返回的值将是高程度的不同的编译器/ STDLIB版本之间的精确一致。

就是这样。

+0

这是我记得被说过的。所以如果我想要更高的准确性,我是否会使用另一个数学库,以及哪一个? x – Xofo 2009-11-07 21:59:30

+1

如果您想确保不同的编译器提供完全相同的值,那么您应该推出自己的sin/cos/tan函数,而不是使用供应商提供的stdlib函数。或者使用这样做的第三方库。自然,这些函数不能调用其他stdlib例程。 或者,您可以生成一组存储为数据文件的触发表,并且您的sin/trig/cos例程将作为查找。 我会问,这是否真的有必要吗?这是我过去不得不做的事情,但肯定不常见。 – 2009-11-07 22:26:14

+1

滚动你自己的点很少。 Netlib是相当标准的http://www.netlib.org/fdlibm/ – 2009-11-07 22:37:58

0

问题不在于标准的数学函数,而在于浮点运算的性质。

非常短的版本:不要比较两个浮点数的相等性,即使有明显的琐碎身份,如10 == 10/3.0 * 3.0tan(x) == sin(x)/cos(x)

1

浮点很简单。请记住,所有浮点运算和函数都存在不确定性组件。它通常被建模为随机的,尽管它通常不是,但如果你把它看作随机的,你将会成功地理解你自己的代码。例如:

a = a/3 * 3;

这应该被视为好像它是:

A =(A/3 + ERROR1)* 3 +误差2;

如果你想估计错误的大小,你需要挖掘每个操作/功能来找出。不同的编译器,参数选择等会产生不同的值。例如,具有5位精度的系统上的0.09-0.089999会产生-0.000001和0.000001之间的某个错误。这个错误的大小与实际结果相当。

如果你想学习如何做到浮动点的精确和可行,那么这是一个由它自己研究。

+0

它不仅是随机的,但你的答案确实没有提供有价值的信息。 – rlbond 2009-11-07 22:38:26

+0

如果你学习数值分析,这就是大学教授的方法,它基本上是计算机上浮点计算的数学。音频工程师不会将其称为随机值,他们会将其称为“噪音”,但这是相同的想法。 我的文章提供了使程序员能够理解的信息,浮点代码中发生错误的位置以及错误的大小。通过将随机值的大小绑定到编译器的选择上,原始问题得到了回答。 – 2009-11-08 09:53:25

+1

在IEEE-754环境中,没有关于浮点的随机事件。浮点不是黑魔法。舍入的存在并不意味着非确定性。 – 2009-11-09 17:51:32

3

例如,您不应该期望sin(PI/6)等于cos(PI/3)。即使x处于sin域,你也不应该指望asin(sin(x))等于x。他们会接近,但可能并不平等。

0

同意所有说你不应该比较平等的答复。你可以做什么,但是,是检查的数字足够接近,就像这样:

if (abs(numberA - numberB) < CLOSE_ENOUGH) 
{ 
    // Equal for all intents and purposes 
} 

哪里CLOSE_ENOUGH一些适当小浮点值。