Java程序中奇怪的浮点行为

Java程序中奇怪的浮点行为

在我的程序中,我有一个具有25个双值0.04的数组,当我试图在循环中对这些值进行求和时,我得到以下结果:


0.0 + 0.04 = 0.04

0.04 + 0.04 = 0.08

0.08 + 0.04 = 0.12

0.12 + 0.04 = 0.16

0.16 + 0.04 = 0.2

0.2 + 0.04 = 0.24000000000000002

0.24000000000000002 + 0.04 = 0.28

0.28 + 0.04 = 0.32

0.32 + 0.04 = 0.36

0.36 + 0.04 = 0.39999999999999997

0.39999999999999997 + 0.04 = 0.43999999999999995

0.43999999999999995 + 0.04 = 0.4799999999999999

0.4799999999999999 + 0.04 = 0.5199999999999999

0.5199999999999999 + 0.04 = 0.5599999999999999

0.5599999999999999 + 0.04 = 0.6

0.6 + 0.04 = 0.64

0.64 + 0.04 = 0.68

0.68 + 0.04 = 0.7200000000000001

0.7200000000000001 + 0.04 = 0.7600000000000001

0.7600000000000001 + 0.04 = 0.8000000000000002

0.8000000000000002 + 0.04 = 0.8400000000000002

0.8400000000000002 + 0.04 = 0.8800000000000002

0.8800000000000002 + 0.04 = 0.9200000000000003

0.9200000000000003 + 0.04 = 0.9600000000000003

为什么会发生这种事?!


侃侃尔雅
浏览 657回答 3
3回答

守候你守候我

程序语言中浮点值最常见的存储-IEEE单打和双打-对大多数十进制分数没有精确的表示。原因是它们以二进制浮点格式存储值,而不是十进制浮点格式。唯一能精确表示的分数值是2的负幂和。数字如下:0.5 (2^-1)0.125 (2^-3)0.625 (2^-1 + 2^-3)等。你所看到的是,像0.96这样的数字的表示并不完全是可表示的,因为它们不能用2的负幂之和来表示。因此,当以十进制小数的形式以完全精确的方式打印出来时,它们将与原始值不匹配。

慕斯709654

亦见“关于浮点,每个计算机科学家都应该知道些什么?"

浮云间

其他答案提到了原因,但没有提到如何避免。有几种解决办法:缩放:如果您的所有数字都是0.01的倍数(例如),那么将所有数据乘以100,并使用整数算术(这是精确的)。数字类型:如果语言具有数字类型(类似于numeric输入SQL),您可以使用它。任意精确理据:使用bignum库,如GMP,它允许您将这些数字表示为两个整数的比率。小数点浮点数:如果您有十进制浮点数,如IEEE-754 r你可以用它。
打开App,查看更多内容
随时随地看视频慕课网APP