BigDecimal精度高于1E22

时间:2014-05-29 12:17:09

标签: java precision bigdecimal

出于某种原因,我发现自己编写了一些软件,应该可以进行一些天文计算。 虽然大部分都是关于将正确的公式转换为Java,但我在“测试如何计算大数字”的开始时发现了一个恼人的问题。

嗯......想象一下太阳(我们的太阳),其质量为(约和圆形,更容易解释)10E30千克。十个跟随零的30个。所有本机数据类型都是不可用的。要提一下:我知道我可以使用3000来计算事物并在输出视图中添加尾随零,但我希望尽可能保持精确。所以使用短号将是我的最后一招。

解决问题。请看一下代码:

    BigDecimal combinedMass = new BigDecimal(1E22);
    int massDistribution = 10;
    Integer mD1 = massDistribution;
    Integer mD2 = 100 - massDistribution;
    BigDecimal starMass;
    BigDecimal systemMass;

    systemMass = combinedMass.divide(new BigDecimal("100")).multiply(new BigDecimal(mD1.toString()));
    starMass = combinedMass.divide(new BigDecimal("100")).multiply(new BigDecimal(mD2.toString()));

    System.out.println((systemMass).toEngineeringString());
    System.out.println((starMass));

它将输出1000000000000000000000和9000000000000000000000,这正是我所期望的。但是看看combineMass Field。如果我将其提高到1E23,输出将改变

我得到9999999999999999161139.20和89999999999999992450252.80 ......

所以我知道我可以使用jut BigInteger,因为它在这种情况下更可靠,但为了预测,有时候BigWhatEver可能会降到50.1258 另外,我希望将10.xE30作为输出,只能使用bigDecimals。

我想知道:有没有办法避免这种情况(对于我尝试过的每个值,错误超过1E23),同时保持计算浮点数的能力?我应该将此字段的After-Decimal-Separator-Values剪切为两个digets吗?

还有更多值得怀疑的事情:

System.out.println(combinedMass.precision());
与上述代码相关的

将为该案例提供23,但对于大多数其他值,则为En + 1(多数民众赞成在我变得非常困惑时)

感谢您的建议。

1 个答案:

答案 0 :(得分:3)

你在没有意识到的情况下使用基本类型:

new BigDecimal(1E22);

这里,1E22是一个原始的双精度,你使用它已经失去了精度。

你想要的是

new BigDecimal("10000000000000000000000");

new BigDecimal(10).pow(22);