2010-10-28 55 views
0

我正在做一些浮点运算,并有精度问题。相同输入的结果值在两台机器上不同。我阅读@Why can't I multiply a float?的帖子,并阅读网络上的其他资料&了解到它是与浮点的二进制表示和机器epsilon有关。但是,我想检查是否有办法解决这个问题/一些解决C++浮点运算?我正在将float转换为unsigned short存储,并在必要时转换回来。但是,当我将它转换回无符号短整型时,精度(至6个小数点)在一台机器上保持正确,但在另一台机器上失败。在C++中有浮点算术问题的解决方案吗?

//convert FLOAT to short 

unsigned short sConst = 0xFFFF; 

unsigned short shortValue = (unsigned short)(floatValue * sConst); 

//Convert SHORT to FLOAT 

float floatValue = ((float)shortValue/sConst); 
+2

究竟是什么问题?事实上,乘法结果在两台不同的机器上稍有不同,这本身并不是问题。为什么它构成你的一个? – 2010-10-28 14:50:34

+0

由于没有提到实际问题,因此无法正确回答此问题。投票结束,这不是一个真正的问题。 – 2010-10-28 15:59:09

+0

更新了问题! – 2010-10-28 16:08:07

回答

2

一个short必须至少为16位,并且在很多实现中都是如此。一个unsigned 16位short将保持从0到65535的值。这意味着一个短不会完整的五位数的精度,当然不是六个。如果你想要六位数字,你需要20位。

因此,任何精度损失都可能是由于您试图将六位数字的精度打包到少于五位的数字。没有解决方案,除了使用可能需要尽可能多的存储作为float的整数类型。

我不知道为什么它似乎在一个给定的系统上工作。你们两个使用相同的数字吗?有没有人使用过旧的浮点系统,并且巧合地给出了你所期望的样本结果?是否可能使用比其他更大的short

1

如果要使用本机浮点类型,你能做的最好的是断言输出的值由您的程序做与一组参考值没有太大差别。

“太多”的确切定义完全取决于您的应用程序。例如,如果您在不同的平台上计算a + b,则应该发现两个结果在对方的机器精度之内。另一方面,如果你正在做一些像矩阵求逆那样更复杂的事情,结果很可能会与机器精度相差甚远。确切地确定你可以期望结果彼此之间有多接近是一个非常微妙和复杂的过程。除非您确切知道自己在做什么,否则确定应用程序下游所需的精度数量可能更安全(更安全),并验证结果是否足够精确。

要获取有关如何计算的相对误差两个浮点值之间的强劲,看到这个答案,浮点导联其中一个想法:

Floating point comparison functions for C#

+0

谢谢菲利普的答案!更新了问题 – 2010-10-28 16:09:02

0

而不是使用0xFFFF使用它的一半,即32768进行转换。 32768(0x8000)具有1000000000000000的二进制表示,而0xFFFF具有1111111111111111的二进制表示。0x8000的二进制表示清楚地表明,在转换期间(在转换回浮动时缩短(或))divsion操作不会改变精度值零后。对于单面转换,无论如何OxFFFF是更可取的,因为它导致更准确的结果。