我在这里阅读有关如何处理大数字的解释,似乎同一类BigNumber也可以用于非常小的数字。
然而,我无法弄清楚如何在不失去精确度的情况下使其发挥作用。
我想在公式中使用0.0000000000012之类的数字,但我不知道如何用BigNumber创建这个数字(如果那是我应该使用的那个),那么当我把它变成一个时,如何避免失去精度在我的等式中使用加倍。
我应该将hte方程中使用的每个数字都作为BigDecimal(即使是具有简单值(12,0.1,...)或仅0.0000000000012的数字应该是BigNumber,我可以肯定我不会失去精度吗?
提前感谢您的帮助, 问候, 乙
答案 0 :(得分:4)
使用课程BigDecimal。它可用于表示任意精度的十进制数。 要从文字中创建一个太精确而不能用double表示的BigDecimal,请使用字符串构造函数:
BigDecimal almostOne = new BigDecimal("0.999999999999999999999999999999999999999987", MathContext.UNLIMITED);
当你将它们转换成双打时,你会失去精确度。因此,BigDecimal类有各种方法来执行基本算术,同时保持精度:
BigDecimal exactlyTen = new BigDecimal(10);
BigDecimal almostTen = almostOne.multiply(exactlyTen);
当您的代码对性能至关重要时,我建议您将问题“What to do with Java BigDecimal performance?”作为进一步阅读。
答案 1 :(得分:3)
String number = "0.0000000000012";
BigDecimal decimal = new BigDecimal(number);
System.out.println(decimal.toString());
decimal = decimal.multiply(new BigDecimal(1000000000000L));
System.out.println(decimal.toString());
这里是代码如何使用和测试BigDecimal Number运行此代码。 Fir sysout将返回 1.2E-12 ,其等值为0.0000000000012。 为了测试这个,将1000000000000的结果乘以1.2。这意味着你不会失去精确度。
答案 2 :(得分:0)
除非精度超过15位有效数字,否则不必使用BigDecimal。你必须使用BigDecimal帮助你的合适的舍入,但这并不意味着你不能用double做同样的事情。
double d = 0.0000000000012;
BigDecimal bd = BigDecimal.valueOf(d);
System.out.println("before d: " + d + " bd: " + bd);
d *= 1000000000000L;
d = Math.round(d * 1e2) / 1e2; // round to two places
bd = bd.multiply(BigDecimal.valueOf(1000000000000L));
System.out.println("after d: " + d + " bd: " + bd);
打印
before d: 1.2E-12 bd: 1.2E-12
after d: 1.2 bd: 1.2000000000000
在效果double
方面,BigDecimal
执行{{1}}的因数为100倍。 BigDecimal也会产生大量垃圾,而double则不会产生任何垃圾。创建大量垃圾不仅速度慢,而且通过向CPU缓存中填充垃圾来减慢所有其余代码的速度。
当我把它变成一个双精度来使用时,如何避免失去精度。
使用double,您需要自己跟踪精度。如果您的函数不知道精度并且您无法告诉它们并且需要传递该值,那么这只是一个问题。即你没有机会完成答案。