昨天我问了一个浮点问题,我有另一个问题。我正在做一些计算,我使用math.h(C语言)正弦,余弦和正切函数的结果。
其中一位开发人员喃喃地说,你必须小心这些函数的返回值,我不应该对gcc数学函数的返回值做出假设。我不是想开始讨论,但我真的想知道在使用标准数学函数进行计算时需要注意什么。
X
答案 0 :(得分:3)
您不应该假设返回的值与不同编译器/ stdlib版本之间的高精度一致。
就是这样。
答案 1 :(得分:3)
例如,你不应该期望sin(PI / 6)等于cos(PI / 3)。你也不应该期望asin(sin(x))等于x,即使x在sin的域中也是如此。它们会很接近,但可能不相同。
答案 2 :(得分:1)
浮点很简单。永远记住,所有浮点运算和函数都有一个不确定性组件。它通常被建模为随机的,即使它通常不是,但如果你把它视为随机的,你将成功地理解你自己的代码。例如:
A = A / 3 * 3;
这应该被视为:
α=(A / 3 + ERROR1)* 3 +误差2;
如果您想估计错误的大小,您需要深入了解每个操作/函数以找出答案。不同的编译器,参数选择等将产生不同的值。例如,对于精度为5位的系统,0.09-0.089999将产生介于-0.000001和0.000001之间的错误。此错误的大小与实际结果相当。
如果你想学习如何使浮点精确到可行,那么它就是它自己的研究。
答案 3 :(得分:0)
问题不在于标准数学函数,而在于浮点运算的本质。
非常短的版本:不要比较两个浮点数的相等性,即使是10 == 10 / 3.0 * 3.0
或tan(x) == sin(x) / cos(x)
等显而易见的琐碎身份。
答案 4 :(得分:0)
你应该注意精确度:
答案 5 :(得分:0)
同意所有回答说你不应该比较平等。但是,您可以做的是检查数字是否足够接近,如下所示:
if (abs(numberA - numberB) < CLOSE_ENOUGH)
{
// Equal for all intents and purposes
}
其中CLOSE_ENOUGH
是一个适当小的浮点值。