我想使用BigDecimal来表示低延迟交易应用程序中的任意精度数字,如价格和金额,每秒有数千个订单和执行报告.
我不会对它们进行很多数学运算,所以问题不在于BigDecimal本身的性能,而在于大量BigDecimal对象会如何影响应用程序的性能.
我担心的是,大量短命的BigDecimal对象会给GC带来压力并导致CMS收集器中更大的Stop-The-World暂停 - 这绝对是我想要避免的.
您能否确认我的疑虑并建议使用BigD的替代方案?此外,如果您认为我的担忧是错误的 - 请解释原因.
更新:
感谢所有回答的人.我现在确信使用BigDecimal会损害我的应用程序的延迟(即使我仍然计划测量它).
目前我们决定坚持使用"非常非OOP"解决方案(但没有精确命中) - 使用两个ints,一个用于尾数,另一个用于指数.这背后的基本原理是基元放在堆栈上,而不是堆,因此不受垃圾收集的影响.
根据JavaDoc for BigDecimal,该compareTo功能不考虑比较期间的比例.
现在我有一个看起来像这样的测试用例:
BigDecimal result = callSomeService(foo);
assertTrue(result.compareTo(new BigDecimal(0.7)) == 0); //this does not work
assertTrue(result.equals(new BigDecimal(0.7).setScale(10, BigDecimal.ROUND_HALF_UP))); //this works
Run Code Online (Sandbox Code Playgroud)
我期望函数返回的值是,0.7并且具有10的标度.打印该值显示预期结果.但是这个compareTo()功能似乎并没有像我认为的那样工作.
这里发生了什么?
是否有可能在C#中获得超过100个十进制数字?
如果是,那么代码的必要部分是什么?
在Java中有一些调用,BigDecimal但它仍然不能达到超过55位数.
我正在处理钱,所以我需要我的结果准确但我只需要2位小数(美分)的精度.BigDecimal是否需要保证乘法/除法的结果是准确的?
BigDecimal.add当一个参数具有大指数(9位数)时,方法需要很长时间,而第二个参数具有不同长度的指数.我已经等了5分钟以上,而且还在继续.
这是代码:
@Test
public void testAddBig() throws Exception {
MathContext mc = new MathContext(10, RoundingMode.HALF_UP);
BigDecimal v1 = new BigDecimal("1E+100000000", mc);
BigDecimal v2 = new BigDecimal("1", mc);
System.out.println(v1.add(v2));
}
Run Code Online (Sandbox Code Playgroud)
这是线程转储的一部分:
at java.math.BigInteger.square(BigInteger.java:1884)
at java.math.BigInteger.squareKaratsuba(BigInteger.java:1975)
at java.math.BigInteger.square(BigInteger.java:1888)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2010)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.pow(BigInteger.java:2263)
at java.math.BigDecimal.bigTenToThe(BigDecimal.java:3543)
at java.math.BigDecimal.bigMultiplyPowerTen(BigDecimal.java:4508)
at java.math.BigDecimal.add(BigDecimal.java:4443)
at java.math.BigDecimal.add(BigDecimal.java:1289)
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?这是一个错误吗?
我正在使用完全基于双精度的应用程序,并且在一个将字符串解析为double的实用程序方法中遇到问题.我找到了一个修复,使用BigDecimal进行转换解决了这个问题,但是当我将BigDecimal转换回double时又引发了另一个问题:我失去了几个精度.例如:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class test {
public static void main(String [] args){
String num = "299792.457999999984";
BigDecimal val = new BigDecimal(num);
System.out.println("big decimal: " + val.toString());
DecimalFormat nf = new DecimalFormat("#.0000000000");
System.out.println("double: "+val.doubleValue());
System.out.println("double formatted: "+nf.format(val.doubleValue()));
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
$ java test
big decimal: 299792.457999999984
double: 299792.458
double formatted: 299792.4580000000
Run Code Online (Sandbox Code Playgroud)
格式化的double表明它在第三位之后失去了精度(应用程序需要较低的精度位置).
如何让BigDecimal保留那些额外的精度位置?
谢谢!
追上这篇文章后更新.有人提到这超出了双数据类型的精度.除非我错误地阅读此引用:http: //java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 然后double原语的最大指数值为E max = 2 K-1 -1,标准实现K = 11.那么,最大指数应该是511,不是吗?
我正在尝试验证大小数的精度和比例.
我希望验证一个大小数不超过10的精度或2的标度.我尝试做一个maxlength所以该值不会违反我的数据库长度限制,但也无法使其工作.有人可以指点我解决这个问题的方向吗?
我在返回BigDecimal值的方法中编写算法,但现在计算的结果将是+或 - 无穷大.
而不是程序崩溃我想捕获异常并返回无穷大作为一个值,如果该方法返回双精度的方式.
例如Double.POSITIVE_INFINITY;
那么如何在BigDecimal中存储无穷大?还是有另一种方法吗?
public static BigDecimal myalgorithm(){
//code to store infinity in a BigDecimal
//return the BigDecimal holding infinity
}
Run Code Online (Sandbox Code Playgroud) bigdecimal ×10
java ×9
c# ×2
.net ×1
algorithm ×1
decimal ×1
double ×1
exception ×1
fixed-point ×1
infinity ×1
performance ×1
precision ×1