读书人

double 40.0*0.05=1.9000000000000001

发布时间: 2012-03-27 13:44:24 作者: rapoo

double 40.0*0.05=1.9000000000000001,要怎样才能让它=2呢?
如果是四舍五入的话总觉得会不正确。

[解决办法]
为什么会不正确?
[解决办法]
double.intValue();
[解决办法]
import java.math.BigDecimal;
public class Arith
{
private static final int DEF_DIV_SCALE = 10;

private Arith()
{

}


/**

* 提供精确的加法运算。

* @param v1 被加数

* @param v2 加数

* @return 两个参数的和

*/

public static double add(double v1,double v2)
{

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.add(b2).doubleValue();

}

/**

* 提供精确的减法运算。

* @param v1 被减数

* @param v2 减数

* @return 两个参数的差

*/

public static double sub(double v1,double v2)
{

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.subtract(b2).doubleValue();

}


/**

* 提供精确的乘法运算。

* @param v1 被乘数

* @param v2 乘数

* @return 两个参数的积

*/

public static double mul(double v1,double v2)
{

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.multiply(b2).doubleValue();

}


/**

* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到

* 小数点以后10位,以后的数字四舍五入。

* @param v1 被除数

* @param v2 除数

* @return 两个参数的商

*/

public static double div(double v1,double v2)
{

return div(v1,v2,DEF_DIV_SCALE);

}



/**

* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指

* 定精度,以后的数字四舍五入。

* @param v1 被除数

* @param v2 除数

* @param scale 表示表示需要精确到小数点以后几位。

* @return 两个参数的商

*/

public static double div(double v1,double v2,int scale)
{

if(scale <0)
{

throw new IllegalArgumentException( "The scale must be a positive integer or zero ");

}

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();

}



/**

* 提供精确的小数位四舍五入处理。

* @param v 需要四舍五入的数字

* @param scale 小数点后保留几位

* @return 四舍五入后的结果

*/

public static double round(double v,int scale){

if(scale <0)
{

throw new IllegalArgumentException( "The scale must be a positive integer or zero ");

}

BigDecimal b = new BigDecimal(Double.toString(v));

BigDecimal one = new BigDecimal( "1 ");

return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();



}


}
(代码来自google 搜索)
以上代码是解决这类问题的

//***************

原因是机器的精确度问题,通常电脑计算方法不是我们通常用的方法.
就好象现在有很多高级计算器一样,他们解方程并不是我们通常用的
解方程公式,而且比较复杂的 "逼近 "方法,
[解决办法]
我觉得高手一般都不用bigdecimal的
[解决办法]
m0317045()的方法确实可行,注意,要使用BigDecimal(String)这个构造函数才可以

另外还有个不常用的方案:

Key: strictfp**

使用对象:类、方法

自Java2以来,Java语言增加了一个关键字strictfp,虽然这个关键字在大多数场合比较少用,但是还是有必要了解一下。

strictfp的意思是FP-strict,也就是说精确浮点的意思。在Java虚拟机进行浮点运算时,如果没有指定strictfp关键字时, Java的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作,以致于得到的结果往往无法令你满意。而一旦使用了 strictfp来声明一个类、接口或者方法时,那么所声明的范围内Java的编译器以及运行环境会完全依照浮点规范IEEE-754来执行。因此如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,那就请用关键字strictfp。

你可以将一个类、接口以及方法声明为strictfp,但是不允许对接口中的方法以及构造函数声明strictfp关键字,例如下面的代码:

1. 合法的使用关键字strictfp

strictfp interface A {}

public strictfp class FpDemo1 {
strictfp void f() {}
}

2. 错误的使用方法

interface A {
strictfp void f();
}

public class FpDemo2 {
strictfp FpDemo2() {}
}

一旦使用了关键字strictfp来声明某个类、接口或者方法时,那么在这个关键字所声明的范围内所有浮点运算都是精确的,符合IEEE-754规范的。例如一个类被声明为strictfp,那么该类中所有的方法都是strictfp的。
[解决办法]
四舍五入
[解决办法]
double 40.0*0.05=1.9000000000000001,
变成float 40.0*0.05=1.9000000000000001,行不?

[解决办法]
m0317045() 的方法看似不错
不过我一般也不这么做
[解决办法]
public class Strictdouble{
public static void main(String[] args){
f1();
f2();
}
strictfp static void f1(){
System.out.println(1.003*1000);//outputs "1002.9999999999999 "
}
static void f2(){
System.out.println(1.003*1000);//outputs "1002.9999999999999 "
}
}

strictfp 关键字在这种地方好像没用

[解决办法]
math.ceil()应该可以

读书人网 >J2SE开发

热点推荐