出于某种原因,我发现自己编写了一些软件,应该可以进行一些天文计算。 虽然大部分都是关于将正确的公式转换为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(多数民众赞成在我变得非常困惑时)
感谢您的建议。
答案 0 :(得分:3)
你在没有意识到的情况下使用基本类型:
new BigDecimal(1E22);
这里,1E22是一个原始的双精度,你使用它已经失去了精度。
你想要的是
new BigDecimal("10000000000000000000000");
或
new BigDecimal(10).pow(22);