Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java十进制大于BigDecimal?_Java_Arrays_Excel_Csv_Bigdecimal - Fatal编程技术网

Java十进制大于BigDecimal?

Java十进制大于BigDecimal?,java,arrays,excel,csv,bigdecimal,Java,Arrays,Excel,Csv,Bigdecimal,这就是我遇到的问题。我有一个CSV文件,我正在阅读4381个小十进制数字,大部分在-5和5之间。例如0.00000822、-0.20929117、-2.204、4.88490078 在我用Java编写的程序中,我读取CSV文件并将所有4381个数字相加,得到一个总和。然而,我得到的总数与正确的数字相差甚远。如果我在Excel中使用=SUM(C:C)将数字列相加,则得到10.77918727。如果我将它们添加到我的程序中,我会得到-933.39114459。正如你所看到的,这些数字甚至一点也不接近

这就是我遇到的问题。我有一个CSV文件,我正在阅读4381个小十进制数字,大部分在-5和5之间。例如
0.00000822、-0.20929117、-2.204、4.88490078

在我用Java编写的程序中,我读取CSV文件并将所有4381个数字相加,得到一个总和。然而,我得到的总数与正确的数字相差甚远。如果我在Excel中使用
=SUM(C:C)
将数字列相加,则得到
10.77918727
。如果我将它们添加到我的程序中,我会得到
-933.39114459
。正如你所看到的,这些数字甚至一点也不接近。我不知道Excel中的值是否正确,但我知道-933对于数据是不正确的

问题是,如果我使用另一个CSV文件中较小的一组数字,那么这些数字的相加是正确的,因此我确信我的程序正确地进行了相加。不管怎样,我已经将用于将数字相加的代码放在下面

因为这些数字在较小的样本中正确相加,所以我能想到的唯一会导致计算出如此不正确的和的事情是我的
sum
变量(称为
gainLoss
)中的位用完了。这就引出了我的问题:有没有一种方法可以在Java中用比BigDecimal更多的位来表示十进制?我已经在使用BigDecimal,它似乎没有提供足够的位,除非我做错了什么

我必须克服BigDecimal的局限性的一个想法是像BigDecimal那样手动使用科学记数法,但我会使用BigDecimal作为基数,BigDecimal作为刻度。唯一的问题是,如果有更好的方法来表示更大的数字,我想避免很多工作

让我知道是否有更好的方法来表示需要大量位的数字,或者我是否做错了什么。我也会接受任何建议

下面是我用来将数字相加的代码(减去我必须首先确保添加数字的所有检查):

//gainLoss是所有数字的总和
BigDecimal gainLoss=新的BigDecimal(0.0);
//数据是CSV文件中所有数据的二维对象数组。
//数据中的第二列用BigDecimal对象填充
for(int i=1;i
编辑:以下是我用于计算总和的完整代码,请参见:

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;
}
公共静态BigDecimal calcGainLoss(对象[][]数据、日历开始、日历结束)
{
BigDecimal gainLoss=新的BigDecimal(“0.0”);
for(int i=1;i
这是一个不太可能的问题,但有时如果数字的大小非常不同,您可能会遇到这样的问题。解决方法是先对数字进行排序,然后首先计算大对之间的差异。您将如何遇到麻烦的示例:

10E38 + 5 - 10E38
将返回0而不是5。但是

10E38 - 10E38 + 5
将返回5(从左到右求值时)。当你按照正确的顺序做事时,你不会因为把它加到10E38中(没有足够的位来存储它)而“丢失5”

然而,“真实世界的数据”会导致舍入误差,其误差之大和你所经历的一样大,这是很不寻常的。您可能以错误的方式解释Excel数据。由于您现在已澄清,当另一列包含“取消”一词时,您没有添加某些数字,因此您可能希望通过计算以下公式确认您实际上得到的答案与Excel不同:

=SUM(C1:C4381) - SUMIF(E1:E4381, "cancel", C1:C4381)
  • 基本上,这表示“对所有元素求和,然后减去它们旁边带有“取消”的元素”
=SUM(C1:C4381) - SUMIF(E1:E4381, "cancel", C1:C4381)