将float转换为BigDecimal然后返回float

时间:2014-05-16 16:57:29

标签: java android floating-point bigdecimal

我正在尝试将float转换为BigDecimal然后做一些数学运算。之后我会要求Float的最终结果。

据我所知,使float成为BigDecimal数的唯一安全方法是使用字符串构造函数。

我有两种方法,但都没有用。两者都给了我额外的0.000001值

方法#1:

Float num1 = 13.846154f;
BigDecimal calculation = new BigDecimal(Float.toString(num1));
BigDecimal num2 = new BigDecimal("2.0").add(calculation);

Float finalResults = num2.floatValue();

方法#2:

Float num1 = 13.846154f;
BigDecimal calculation = new BigDecimal(Float.toString(num1));
BigDecimal num2 = new BigDecimal("2.0").add(calculation);

Float finalResults = Float.parseFloat(num2.toString());

当我将数字转换回浮动时,有没有办法安全地进行数学运算而不会失去精度?

编辑#1 我做了一些测试,发现了一些奇怪的东西。

Float original = 13.846154f;

BigDecimal originalNum = new BigDecimal(Float.valueOf(original));

BigDecimal numTwo = new BigDecimal("14.0"); 
BigDecimal numThree = new BigDecimal("20.0");
BigDecimal numFour = new BigDecimal("30.0");

numTwo = numTwo.add(originalNum);
numThree = numThree.add(originalNum);
numFour = numFour.add(originalNum);

它还在增加额外的0.000001 ..

2 个答案:

答案 0 :(得分:2)

如果你想避免失去任何精度,你必须一直使用BigDeciml,使用一点BigDecimal可能毫无意义。

我建议使用double,它的准确度是10亿倍(真的是~10 ^ 9 *)

如果您要使用float,请不要使用Float,因为这只会增加开销,无益。

如果您执行13.846154,则这比float支持的更精确。

System.out.println(13.846155f);
System.out.println(23.846155f);
System.out.println(33.846155f);

打印

13.846155
23.846155
33.846153 <- a representation error with this many digits.

相反,我建议你尝试

double finalResult = 13.846154 + 2.0;

顺便说一句

 System.out.println(13.846154+ 2.0);

打印

 15.846154

答案 1 :(得分:2)

new BigDecimal(double)构造函数与从floatdouble的转换完全相同,因此如果您从floatnum1开始,{{ 1}}将提供准确的new BigDecimal(num1)等价物。

这可能不是您所期望的。例如,最接近的BigDecimal到13.846154是13.84615421295166015625,因此这是floatnum1的初始值。

calculation加2是准确的,给出15.84615421295166015625。

下一个问题是将其转换为BigDecimal以进行进一步计算。碰巧的是,它完全可以表示为float,因此不会进一步降低精度。一般情况下,将float转换为BigDecimal将涉及四舍五入到最近的float

事实证明,此计算中的所有精度损失都发生在float的初始化上。如果你这样做,没有与String之间的所有转换,只要初始使用num1,你就会尽可能接近。

如果float对于您的计算不够精确,但您需要float传递给其他方法,请考虑使用floatBigDecimal进行整个计算除了最后一步。 double BigDecimal确实会将最接近的floatValue()返回到float的确切值。

有一种情况,使用BigDecimal是有利的。如果您知道您希望BigDecimal是一个精确的小数部分,那么从该分数的String表示构造String就可以得到它。写BigDecimal之类的内容会得到new BigDecimal(1.0),其值为0.1000000000000000055511151231257827021181583404541015625,最接近的值的值为0.1。如果您已转换为BigDecimalfloat,则通过double转换将无效或导致精度损失。它无济于事。