关于java中float的循环增值问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于java中float的循环增值问题相关的知识,希望对你有一定的参考价值。

我定义了一个float值的变量,然后再for循环里打印,每次循环加0.1,然后每十个循环打印一次,也就是说循环40次打印出来的应该是1234,但是它出来的确实1223,我调试过了,它在循环加0.1的过程当中,有时候会变成1.0000001这样的,第29次按理说加完0.1应该是3.0,但它却显示是2.9999999,前几次还正常,然后就变不正常,然后又变正常。这是为什么?求解!!!

参考技术A 受限于计算机中存储位数,浮点数的精度有限。举个例子说,1/3你用纯数学表达可以说是0.33333333....后面无限个3。但用float类型的变量保存时,就得截断了,比如0.3333333,这样它就跟实际的值有了一个微小的差别(0.0000000333333....),这些差别累积起来会导致比较大的差别(就是你做累加操作时遇到的情况)。追问

请问要怎么解决呢?

追答

如果你最后是把结果取整了,那用四舍五入(比如结果加0.5然后取整),不要舍弃小数部分。
int(1223.9999999) ==> 1223
int(1223.9999999+0.5) ==> 1224

追问

不对阿,我加的的0.1,不是无限循环小数,所以应该不会存在小差别从未导致大差别,还是说我加的时候应该精确中写道:0.1000000?

追答

你说的"第29次按理说加完0.1应该是3.0,但它却显示是2.9999999",int(2.9999999)==>2,这不就跟3差了1吗?

追问

对阿,我就是想知道为什么加着加着会出现这样的小差错。按你说的,无限循环小数转成float会被截短,所以会产生小差错,但是我加的是0.1,应该是不存在小差错的阿。还是说float在加的过程中就会形成无限小数,所以会产生小差错?

参考技术B 计算机在存储浮点数时的机制造成的。
浮点数以【有限】的32bit长度来反映【无限】的实数集合,因此大多数情况下都是一个近似值。
这种解决方法:显示时四舍五入到具体的精度。(注意java默认的舍入规则是四舍六入,无看奇偶,即银行舍入法)追问

这样会影响到显示的数据吗?会正常的显示123456789这样吗?

参考技术C 精确计算数据,比如金钱的计算 一般用
BigDecimal
这个类。追问

请问怎么用?需要调用这个类的哪个方法?

追答

http://pan.baidu.com/share/link?shareid=1543030639&uk=1478079121

这个地址是
java api
初学者多看看。
http://www.javaweb.cc/JavaAPI1.6/

http://www.javaweb.cc/JavaAPI1.6/java/math/BigDecimal.html

追问

能告诉我具体哪个方法吗,我并不要学这个,按照你的思路你会怎么解决,写出来就行了。

追答

BigDecimal b1 = new BigDecimal(2.15D);
BigDecimal b2 = new BigDecimal(3.14D);
System.out.println("b1+b2="+b1.add(b2).doubleValue());

追问

两数相减怎么写?

追答

上边是api,各种复杂的算法都有。包括四舍五入==

追问

好,已经解决了,谢谢你。

本回答被提问者采纳

关于FreeMarker的list循环取值问题

我定义$item[0].items[0].name可以正常取items[0]的name值,但是我要是循环遍历items中的name值,即

<#list item[0].items as x>
var listArray = [];
listArray[$x_index] = "$(x.name)!""";
</#list>
就会报错
Expected collection or sequence. item[0].items evaluated instead to freemarker.template.SimpleHash on line 81, column 24 in index.ftl.
想知道这个怎么操作?谢谢
我改为<#list $item[0].items as x>报的是这个错误:

Exception in thread "main" freemarker.core.ParseException: Encountered "" at line 81, column 25 in index.ftl.
Was expecting one of:
"as" ...
"." ...
"[" ...
"(" ...
"?" ...
"!" ...
<TERMINATING_EXCLAM> ...

参考技术A 去看看freemarker表达式怎么用的就知道了,看是否正确,或者和其他表示方式有冲突吧。

以上是关于关于java中float的循环增值问题的主要内容,如果未能解决你的问题,请参考以下文章

关于java list循环的问题

关于java的double类型和float类型

关于java中的数据类型

关于FreeMarker的list循环取值问题

关于java的continuebreak关键字用法

关于递归,Java 中的 for 循环。在这种情况下我的理解正确吗?