2012-10-02 69 views
2

我想获得小数部分从双,这是我的代码,以获得小数部分减去双给出错误的结果

double decimalvalue = 23423.1234-23423.0; 
0.12340000000040163 

但减去之后我期待decimalvalue是0.1234,但我得到0.12340000000040163。请帮助我理解这种行为,以及是否有任何解决方法。

+1

有无限多的实际值,而在双只有64位。 – user7116

+3

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Mysticial

回答

8

我建议你看看

What Every Computer Scientist Should Know About Floating-Point Arithmetic

Wikipedia: IEEE 754

有值的数量有限,你可以在一个浮点数指定,但浮点数的无限数量代表的范围。

因此,某些浮点数不能精确地表示任何浮点/双精度数据类型。

处理您的具体问题的典型方法是避免直接的平等比较,而是做一个epsilon测试:查看期望值和计算值是否在一些小数字内(与减去的值相比),称为epsilon,彼此。

间接关系是Machine Epsilon概念,值得一看在一个完整的理解

+1

Epsilon应该适合被比较数量的大小。 – user7116

+0

@sixlettervariables:这是一个很好的观点。编辑。 –

+0

另请参见:http://www.parashift.com/c++-faq/floating-point-arith2.html – Ghost2

3

这是舍入错误。在基数10中,你不能完全代表给定数字位数的1/3(比如15)。在基数2中,有很多东西你不能表示,0.1234恰好是其中之一。精度取决于比例尺,但对于双精度值大约为15位十进制数字。我建议看看http://en.wikipedia.org/wiki/IEEE_floating_point了解更多关于浮点数的细节。

如果您正在尝试构建一个基本10系统(例如人为使用的计算器)并且您需要确切的结果,则应该使用BCD。

+0

“......你不能用*有限精度*表示。” – user7116

+0

大声笑,我正要修改自己:P – CrazyCasta