# Java学习笔记:关于Java double类型相加问题

## Java double类型相加问题

java.math.*里面提供了BigDecimal类（提供高精度计算的方法）

### 一、这个时候就要采用BigDecimal函数进行运算

BigDecimal（double）或者BigDecimal(Double.valueOf(double)))

`new BigDecimal(Double.toString(double)).add(new BigDecimal(Double.toString(double));`

`    /**     * @param b1     *            BigDecimal     * @param v2     *            double     * @return BigDecimal     * */    public BigDecimal add(BigDecimal b1, double v2) {        // BigDecimal b1=new BigDecimal(Double.toString(v1));        BigDecimal b2 = new BigDecimal(Double.toString(v2));        return b1.add(b2);    }`

`    /**     * @param b1     *           double     * @param v2     *            double     * @return BigDecimal     * */    public BigDecimal add(double v1, double v2) {         BigDecimal b1=new BigDecimal(Double.toString(v1));        BigDecimal b2 = new BigDecimal(Double.toString(v2));        return b1.add(b2);    }`

`    /**     * @param b1     *           double     * @param v2     *            double     * @return double     * */    public 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();    }`

### 二、double 三种加法比较

+，strictfp，BigDecimel

Strictfp —— Java 关键字。

`public class MathDemo {    /**     * @param args     */    public static void main(String[] args) {        System.err.println("普通 "+ addNormal(12353.21,21334.24,154435.03));        System.err.println("strictfp "+addDouble(12353.21,21334.24,154435.03));        System.err.println("BigDEcimel: "+add(12353.21,21334.24,154435.03));    }    public static double addNormal(double... v1) {        double res = 0;        for (int i = 0; i < v1.length; i++) {            res += v1[i];        }        return res;    }    public static strictfp double addDouble(double... v) {        double res = 0;        for (int i = 0; i < v.length; i++) {            res += v[i];        }        return res;    }    /**     * @param b1     *            double     * @param v2     *            double     * @return double     */    public static double add(double... v) {        BigDecimal b  = new BigDecimal(Double.toString(v[0]));        for (int i = 1; i < v.length; i++) {            BigDecimal b2 = new BigDecimal(Double.toString(v[i]));            b=b.add(b2);        }        return b.doubleValue();    }}`

12353.21,21334.24,154435.03三个类型的数据时候

strictfp 188122.47999999998

BigDEcimel: 188122.48

3.21, 4.24,5.03

strictfp 12.48

BigDEcimel: 12.48

12353.21,21334.24

strictfp 33687.45

BigDEcimel: 33687.45

BigDecimal的算法精度比较好。 其余两种方法 都存在缺点。至于strictfp 这个关键字 是去平台化影响。比如32为机器和64位机器结果都一样。 对于精度计算结果影响不大。

`//使用double类型创建BigDecimal  public BigDecimal(double val) {        if (Double.isInfinite(val) || Double.isNaN(val))            throw new NumberFormatException("Infinite or NaN");        // Translate the double into sign, exponent and significand, according        // to the formulae in JLS, Section 20.10.22.        long valBits = Double.doubleToLongBits(val);        int sign = ((valBits >> 63)==0 ? 1 : -1);        int exponent = (int) ((valBits >> 52) & 0x7ffL);        long significand = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1                            : (valBits & ((1L<<52) - 1)) | (1L<<52));        exponent -= 1075;        // At this point, val == sign * significand * 2**exponent.        /*         * Special case zero to supress nonterminating normalization         * and bogus scale calculation.         */        if (significand == 0) {            intVal = BigInteger.ZERO;            intCompact = 0;            precision = 1;            return;        }        // Normalize        while((significand & 1) == 0) {    //  i.e., significand is even            significand >>= 1;            exponent++;        }        // Calculate intVal and scale        long s = sign * significand;        BigInteger b;        if (exponent < 0) {            b = BigInteger.valueOf(5).pow(-exponent).multiply(s);            scale = -exponent;        } else if (exponent > 0) {            b = BigInteger.valueOf(2).pow(exponent).multiply(s);        } else {            b = BigInteger.valueOf(s);        }        intCompact = compactValFor(b);        intVal = (intCompact != INFLATED) ? null : b;    }`

## Java double类详解

### Double 类的构造方法

Double 类中的构造方法有如下两个。

• `Double(double value)`：构造一个新分配的 Double 对象，它表示转换为 double 类型的参数。

• `Double(String s)`：构造一个新分配的 Double 对象，它表示 String 参数所指示的 double 值。

`Double double1 = new Double(5.556);    // 以 double 类型的变量作为参数创建 Double 对象Double double2 = new Double("5.486");       // 以 String 类型的变量作为参数创建 Double 对象`

### Double 类的常用方法

`String str = "56.7809";double num = Double.parseDouble(str);    // 将字符串转换为 double 类型的数值double d = 56.7809;String s = Double.toString(d);    // 将double类型的数值转换为字符串`

### Double 类的常用常量

• `MAX_VALUE`：值为 1.8E308 的常量，它表示 double 类型的最大正有限值的常量。
• `MIN_VALUE`：值为 4.9E-324 的常量，它表示 double 类型数据能够保持的最小正非零值的常量。
• `NaN`：保存 double 类型的非数字值的常量。
• `NEGATIVE_INFINITY`：保持 double 类型的负无穷大的常量。
• `POSITIVE_INFINITY`：保持 double 类型的正无穷大的常量。
• `SIZE`：用秦以二进制补码形式表示 double 值的比特位数。
• `TYPE`：表示基本类型 double 的 Class 实例。