什么时候double精度出现问题,可以用BigDecimal代替?

ylchen.xd 发布于 2012/12/16 00:11
阅读 2K+
收藏 0

网上搜来的算法题,自己做了做。刚开始没有想到BigDecimal,做完出结果之后觉得数据可能出现精度问题,于是用了BigDecimal试了一下。发现两次结果一样。两段代码如下。

比较疑惑,书上说在进行算数运算的时候double可能会出现精度丢失,但是具体什么时候精度丢失需要BigDecimal来修正呢?求解。

题目:一个球从100米高度自由落下,每次落地后反弹回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第十次反弹高度多高?

BigDecimal:

import java.math.*;;
public class BounceBall
{
	private static final int DEF_DIV_SCALE = 10;
	public static void main(String[] args)
	{
		double h = 100.0;
		double sum = h;
		byte n = 10;
		for(int i = 0; i < n; i ++)
		{
			h = div(h,2);
			sum += 2*h;
		}
		System.out.println("h = " + h + ",sum = " + sum);
	}
	public static double div(double d1 , double d2)
	{
		BigDecimal b1 = BigDecimal.valueOf(d1);
		BigDecimal b2 = BigDecimal.valueOf(d2);
		return b1.divide(b2 , DEF_DIV_SCALE , 
			BigDecimal.ROUND_HALF_UP).doubleValue();
	}
}
double:

public class BounceTest
{
	public static void main(String[] args)
	{
		double h = 100.0;
		double sum = h;
		byte n = 10;
		for(int i = 0; i < n; i ++)
		{
			h = h/2;
			sum += 2*h;
		}
		System.out.println("h = " + h + ",sum = " + sum);
	}
}
两段代码结果一样:

加载中
0
Seventh7
Seventh7
你改成除3再乖3结果就不同了
0
random_walk
random_walk

public static void main(String[] args) {
		double d=4.0;
		System.out.println(foo(d,10));
		System.out.println(foo(d,50));
		System.out.println(foo(d,53));
	}

	static double foo(double d, int iter) {
		for (int i = 0; i < iter; i++) {
			d = Math.sqrt(d);
		}
		for (int j = 0; j < iter; j++) {
			d = d*d;
		}
		return d;
	}

Out:

4.000000000000094
3.490342924893666
1.0


	public static void main(String a[]) {
		System.out.println( Math.pow(0.2, 1000) );
		
		BigDecimal num=new BigDecimal("0.2");
		System.out.println(num.pow(1000));
	}


下面这段代码用double的精度也是不够的,http://www.oschina.net/code/snippet_103482_13051

0
李文轩
李文轩

1.二进制,乘除2一般不会造成精度损失

2.你的调用深度还不够

3.最重要的是,不损失精度要求一直用BigDecimal,你一会用一会又转回double,再好的精度也损失完了

4.double的精度范围是16位十进制有效数字

0
南湖船老大
南湖船老大

楼主只知其一,不知其二

二进制,乘除2一般不会造成精度损失,这个不解释。

除得尽,也不代表精度不会丢失。原理不废话,就是二进制运算,小数转二进制,可能永远都无法结束,只能取近似值。大数运算就是把数字变成字符串,像小学生一样逐位运算。

这块的知识,可以看《计算机文化基础》的二进制介绍一块。基本上高校里任何专业都有这门课的(中学也有了吧),这是基础知识,跟打字上网用word一样,都算不上计算机专业知识了。

返回顶部
顶部