黑马程序员技术交流社区
标题:
分析打印不出结果的原因
[打印本页]
作者:
冯佩
时间:
2013-2-17 12:27
标题:
分析打印不出结果的原因
本帖最后由 冯佩 于 2013-2-20 15:11 编辑
public class Test
{
public static void main(String[] args)
{
double item = 1;
double sum=0;
while(item != 0)
{
sum += item;
item -= 0.1;
}
System.out.println("sum="+sum);
}
}
以上是对1+0.9+0.8+...+0.1进行求和的一种代码编写方式,请分析打印不出结果的原因。
作者:
王昕
时间:
2013-2-17 13:01
本帖最后由 王昕 于 2013-2-17 13:23 编辑
经过调试发现,-0.1之后,item就变成了0.90000000000000002,每步的结果都有误差,不是刚好减0.1,所以item一直都不等于0,所以一直循环。
作者:
燕国庆
时间:
2013-2-17 13:23
public class Test
{
public static void main(String[] args)
{
double item = 1;
double sum=0;
while(item != 0) //
这段代码在河的时候出现了死循环,所以JVM无法执行输出语句 System.out.println("sum="+sum);
{
sum += item;
item -= 0.1;
}
System.out.println("sum="+sum);
}
}
作者:
张晋瑜
时间:
2013-2-17 13:26
因为这个循环永远不会结束
作者:
张晋瑜
时间:
2013-2-17 13:30
while(item != 0)
{
sum += item;
item -= 0.1;
}
由于你用的是double型数据,当item=0.8自减到0.7时得到的是item=0.7000000000000001
你调试一下,会发现不会出现item=0.00000000000000的情况
作者:
康乐
时间:
2013-2-17 16:59
本帖最后由 康乐 于 2013-2-17 17:02 编辑
由于在-0.1时结果不够精确,所以出现了死循环。调试时会发现item在减了0.1几次以后结果就会不够精确。
java中floa或者double运算时可能会丢失精度,因为十进制小数转换成二进制数时表示可能不够精确,就像十进制系统中能不能准确表示出1/3,同样二进制系统也无法准确表示1/10。float和double只能用来做科学计算或者是工程计算,在精确的计算中我们要用java.math.BigDecimal。通常用的构造方法是以下两个:
BigDecimal(double val)
BigDecimal(String val)
第一个构造方法虽然用起来方便但是有一定的不可预知性,具体在API中有介绍
所以如果需要精确计算,最好用String来够造BigDecimal。
需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用方法,传入另一个作为参数,
然后把运算的结果(BigDecimal)再转换为浮点数。
主函数总这样写
double item = 1;
double sum=0;
while(item != 0)
{
sum += item;
BigDecimal bdItem = new BigDecimal(Double.toString(item));
BigDecimal bd = new BigDecimal("0.1");
item = bdItem.subtract(bd).doubleValue();
}
System.out.println("sum="+sum);
复制代码
作者:
胥文
时间:
2013-2-17 22:01
public static void main(String[] args) {
double temp =1;
double sum = 0;
while(temp !=0)
{
sum+=temp;
temp = temp-0.1;
//使用给定的模式(小数保留一位)创建一个DecimalFormat对象
DecimalFormat df = new DecimalFormat(".0");
//将temp按照指定的格式格式化之后,在转化成Double
temp = Double.valueOf(df.format(temp));
System.out.println(temp);
}
System.out.println(sum);
}
}
已经验证,这样就是你要的结果
作者:
黄玉昆
时间:
2013-2-17 23:13
你试试这段代码,应该是没问题的了:
public class Test
{
public static void main(String[] args)
{
int item = 10;
float sum=0f;
while(item != 0)
{
sum += item;
item -= 1;
}
System.out.println("sum=" + (sum/10));
}
}
复制代码
这里的float的范围要大于int,所以是可以进行sum+=item语句的。但是不能将sum定义为int,否则打印结果为int型了。
作者:
冯佩
时间:
2013-2-18 03:37
感谢各位的参与,在循环中请尽量不要使用浮点值来比较值是否相等,因为浮点值都是某些值的近似值,所以不能确保item会变成真正的0,从表面上看,这个循环似乎没问题,但实际上它是一个无限循环。
作者:
罗海清
时间:
2013-2-18 10:19
都很牛,楼主可以变成已解决了
作者:
铿锵科技
时间:
2013-2-18 12:51
double item = 1;
double sum=0;
while(item != 0)
{
sum += item;
item -= 0.1;
}
System.out.println("sum="+sum);
我是这样理解的:
java中switch()中不可使用浮点数来判断条件,同理while中也不会使用浮点数来判断条件,所以如果在while中判断条件的数值类型应该用整型
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2