這是我遇到的問題。我有一個CSV文件,我讀的是4381個小數,大部分在-5和5之間。他們的例子是0.00000822, -0.20929117, -2.204, 4.88490078
。Java小數大於BigDecimal?
在我用Java編寫的程序中,我正在讀取CSV文件並將所有4381號碼加在一起得到一筆款項。但是,我得到的總和甚至沒有接近正確的數字。如果我使用=SUM(C:C)
將Excel中的數字列添加到Excel中,我會得到10.77918727
。如果我將它們加在我的程序中,我會得到-933.39114459
。正如你所看到的,這些數字甚至不是很接近。我不知道Excel的價值是否正確,但我知道數據無法正確-933。
問題是,如果我使用另一個CSV文件中較小的一組數字,那麼這些數字會正確合計,所以我確信我的程序正確地進行了添加。無論如何,我已經將我正在使用的代碼添加到下面的代碼中。
因爲數字與較小的樣本加起來正確的,我能想到的唯一的事情會導致出現這樣計算不正確的總和我在我的sum
變量(稱爲gainLoss
)用完位。這使我想到了我的問題:有沒有一種方法可以用Java中比使用BigDecimal更多的位來表示小數位?我已經在使用BigDecimal,它似乎不提供足夠的位,除非我做錯了什麼。
一個想法,我不得不避開BigDecimal的限制是手動用科學記數法像BigDecimal的做法,但我會用一個BigDecimal爲基礎,一個BigDecimal爲標尺。唯一的問題是,如果有更好的方法來表示更大的數字,那麼我想避免的工作似乎很多。
讓我知道是否有更好的方法來表示數字需要大量的位或者如果我做錯了什麼。我也會採取任何建議。
這裏是我使用添加的數字相加(減去所有我必須做的,首先要確定應加入一些支票)代碼:
// gainLoss is the sum of all the numbers
BigDecimal gainLoss = new BigDecimal(0.0);
// data is a 2D Object array of all the data from the CSV file.
// The 2nd column in data is filled with BigDecimal objects
for (int i = 1; i < data.length; i++) // for each data row in data (excluding the header row)
{
// set rowAmt to the value of the number in the current row of the CSV file
BigDecimal rowAmt = (BigDecimal)data[i][2];
// add this row's value to gainLoss
gainLoss = gainLoss.add(rowAmt);
}
編輯:以下是完整的代碼我使用來計算的總和,如要求:
public static BigDecimal calcGainLoss(Object[][] data, Calendar startCal, Calendar endCal)
{
BigDecimal gainLoss = new BigDecimal("0.0");
for (int i = 1; i < data.length; i++) // for each data row in data
{
int lineNum = i + 1;
System.out.println("Line " + lineNum + ", i " + i + ": " + gainLoss.toString());
// Load the important values into memory
String rowType = (String)data[i][4];
BigDecimal rowAmt = (BigDecimal)data[i][2];
Calendar rowDate = (Calendar)data[i][1];
// Check if this row should be included in the calculations based on its row type
if (rowType.equalsIgnoreCase("cancel")) // if this was a cancelled transaction
{
continue; // move on to the next row
}
// Check if this row should be included in the calculations based on its date
boolean rowIsIncludedDate = false; // whether this row is within the given date range
if ((startCal == null) && (endCal == null)) // if no start or end date was given
{
rowIsIncludedDate = true;
}
else if ((startCal == null) && (!rowDate.after(endCal))) // if no start date was given and the current row's date is before or equal to the end date
{
rowIsIncludedDate = true;
}
else if ((endCal == null) && (!rowDate.before(startCal))) // if no end date was given and the current row's date is equal to or after the start date
{
rowIsIncludedDate = true;
}
else if ((!rowDate.before(startCal)) && (!rowDate.after(endCal))) // if both dates were given and the current row's date is equal to or after the start date and equal to or before the end date
{
rowIsIncludedDate = true;
}
if (!rowIsIncludedDate) // if this row should not be included in the calculation because its date is outside of the requested range
{
continue; // go on to the next row
}
// Add the current row's value to the current sum
gainLoss = gainLoss.add(rowAmt);
System.out.println("Adding " + rowAmt.toString());
}
return gainLoss;
}
你學到了通過你的代碼調試器步進什麼? –
我其實從來沒有嘗試過。我現在要做。 – cmasupra
或者通過插入打印輸出,以便在運行過程中觀察過程? (你確定你已經正確地填充了數據[] []嗎?) – keshlam