使用Java将double值转换为BigInteger值的最佳方法

时间:2015-04-09 09:00:30

标签: java double biginteger

有没有一种方法可以将double值转换为BigInteger值,以后再回来?在最好的情况下,不会丢失数据。问题是,我不知道double值有多少小数位。但我需要这种转换为一种只适用于非十进制值的算法。算法完成后,我必须将其转换回来。

我需要的一个简单示例:例如2个double值的总和,但“sum”函数仅适用于BigInteger。

3 个答案:

答案 0 :(得分:5)

您可以分5个步骤完成:

double d1 = 0.1; //your original double
BigDecimal bd1 = new BigDecimal(d1); //convert to BigDecimal
BigInteger bi = bd1.unscaledValue(); //convert to BigInteger
//here do your stuff with the BigInteger
BigDecimal bd2 = new BigDecimal(bi, bd1.scale()); //back to BigDecimal, applying scale
double d2 = bd2.doubleValue(); //convert to double

应用于sum方法的完整示例

输出:

  

0.1 + 0.1 = 0.2
  0.1 + 10.1 = 10.2
  0.1245 + 17.0 = 17.1245

代码:

public static void main(String[] args) {
  test(0.1, 0.1);
  test(0.1, 10.1);
  test(0.1245, 17);
}

private static void test(double d1, double d2) {
  System.out.println(d1 + " + " + d2 + " = " + sum(d1, d2));
}

private static double sum(double d1, double d2) {
  BigDecimal bd1 = new BigDecimal(d1);
  BigDecimal bd2 = new BigDecimal(d2);

  int shift = Integer.max(bd1.scale(), bd2.scale());

  BigInteger bi1 = bd1.scaleByPowerOfTen(shift).toBigInteger();
  BigInteger bi2 = bd2.scaleByPowerOfTen(shift).toBigInteger();

  BigInteger sum = sum(bi1, bi2);

  return new BigDecimal(sum, shift).doubleValue();
}

private static BigInteger sum(BigInteger i1, BigInteger i2) {
  return i1.add(i2);
}

答案 1 :(得分:4)

此程序基于BigDecimal和scale规范,如assylias's answer中所述,但已修改为无条件使用最大可能需要的比例。这允许在数字流中使用相同的比例,而无需在处理任何数字之前查看所有数字。成本是它通常会返回不必要的大BigInteger值。

比例因子“1e1074”基于以下观察:所有有限双数是Double.MIN_VALUE的整数倍,其在小数点后有1074个十进制数字。小数点后面没有双精度数。

import java.math.BigDecimal;
import java.math.BigInteger;

public class Test {
  public static void main(String[] args) {
    testit(Double.MIN_VALUE);
    testit(Double.MAX_VALUE);
    testit(0);
    testit(1.0);
    testit(Math.E);
    testit(Math.PI);
  }

  private static void testit(double d) {
    double roundTrip = scaledIntegerToDouble(doubleToScaledInteger(d));
    if (d != roundTrip) {
      System.out.println("ERROR: " + d + " " + roundTrip);
    }
  }

  public static final BigDecimal scale = new BigDecimal("1e1074");

  public static BigInteger doubleToScaledInteger(double d) {
    BigDecimal bd = new BigDecimal(d).multiply(scale);
    return bd.toBigIntegerExact();
  }

  public static double scaledIntegerToDouble(BigInteger bi) {
    BigDecimal bd = new BigDecimal(bi).divide(scale);
    return bd.doubleValue();
  }
}

答案 2 :(得分:1)

package test;

import java.math.*;

public class HelloWorld{

    public static BigInteger sumBigInteger(BigInteger n1,BigInteger n2){
        return n1.add(n2);
    }

    public static double sumDouble(double n1,double n2){
        int scale=1;
        int max = Math.max(((""+n1).split("\\."))[1].length(), ((""+n2).split("\\."))[1].length());
        for (int i=0;i<max;i++) scale*=10;
        BigInteger nbr1 = new BigDecimal(n1*scale).toBigInteger();
        BigInteger nbr2 = new BigDecimal(n2*scale).toBigInteger();
        return (sumBigInteger(nbr1,nbr2).doubleValue() / scale);
    }

     public static void main(String []args){    
         double n1=117.22 , n2=56.945;
         System.out.println(n1+" + "+n2+" = "+sumDouble(n1,n2));    
     }
}

<强>输出:

117.22 + 56.945 = 174.165
相关问题