将Double转换为BigDecimal时获取NaN / Infinity错误

时间:2015-03-23 15:31:07

标签: java double bigdecimal

所以我在double之间进行了这种划分(来自数据库中的值);

 indPayRatio[loadCounter] = c.getDouble(c.getColumnIndex("payment")) / c.getDouble(c.getColumnIndex("debt_total"));

没有任何一个值可以为空的情况。他们必须在这里做点什么。

我有时会得到这个疯狂的长数字,所以我将其转换为BigDecimal,如此:

 bdRatio = new BigDecimal(indPayRatio[i]);

在这一行,我从许多用户那里获得了以下堆栈跟踪。我无法复制它,所以我不确定它的价值。

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NumberFormatException: Infinity or NaN: NaN
at java.math.BigDecimal.<init>(BigDecimal.java:465)
at com.---.---.DebtDataSource.payoffDebt(DebtDataSource.java:544)
at com.---.---.PlannerFragment$PlannerTask.doInBackground(PlannerFragment.java:177)
at com.---.---.PlannerFragment$PlannerTask.doInBackground(PlannerFragment.java:143)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 4 more

我的第一个预感是,我应该使用BigDecimal乘以第一行,但如果这是问题,为什么我在将其转换为BigDecimal时会收到错误?< / p>

1 个答案:

答案 0 :(得分:0)

所以我做了两件事来帮助解决这个问题。最重要的是,我不再使用double进行重度划分,而是BigDecimal。我相信旧的方式导致NaN值。如上所述,我也发现传递0坠毁了BigDecimal师。

我改变了这个:

indPayRatio[loadCounter] = c.getDouble(c.getColumnIndex("payment")) / c.getDouble(c.getColumnIndex("debt_total"));

为:

BigDecimal dPayment = new BigDecimal(c.getDouble(c.getColumnIndex("payment")));
BigDecimal dTotal = new BigDecimal(c.getDouble(c.getColumnIndex("debt_total")));
if (dPayment.equals(BigDecimal.ZERO) || dTotal.equals(BigDecimal.ZERO)) {
    indPayRatio[loadCounter] = BigDecimal.ZERO;
} else {
    MathContext mc = new MathContext(2, RoundingMode.HALF_EVEN);
    indPayRatio[loadCounter] = dPayment.divide(dTotal, mc);
}