The excel column contains numbers from 1 to 0.0001. When the operator manually summarizes a column from about 10-30 lines, the number is 15.028

I do automation. I get data from the DB Oracle. Information comes in the form of strings. I convert strings to Double and summarize. The sum of the same lines gives me 13.9

Can Double round off values ​​because of what information is lost and how to deal with it?

for (String[] rowx : СписокмассивовстрокИзОракл) { String key = "комбинация данных по логике автоматизации"; try { if (mapMass.containsKey(key)) { try { double src = 0.0; try { src = Double.valueOf(rowx[timeFakt]); //косяк, данные хранящиеся в ячейке timeFakt могут быть типа 0,0028 или 0,0000034. и они округляются. } catch (Exception e) { e.printStackTrace(); } total = Double.valueOf(mapMassTwo.get(key)) + src; String tf = String.valueOf(total); mapMassTwo.put(key, tf); total = 0.0; } catch (Exception e) { e.printStackTrace(); } } else { String tf = rowx[timeFakt]; mapMass.put(key, tf ); } } catch (Exception e) { e.printStackTrace(); } } 
  • Possible duplicate question: Calculations on floating point numbers do not work - rdorn
  • Excel summarizes not what it shows, but real double values ​​with which it works internally. It shows already rounded values. - rdorn
  • one
    @Padawan "A couple of dozen lines" - and an error of 15%? Something is not right here. Show the code and data. It is also advisable to write down what numbers you get from these lines. - Igor
  • @Igor up to 50% of the error of the amount when working with rounded values ​​may well be: 1.4 + 1.4 = 2.8 rounding - 3, the same with the preliminary rounding of the items will give 1 + 1 = 2, here's 50% of the error on level ground. - rdorn
  • @rdorn This, of course, is possible, but the author writes about the result with a fractional part, so it seems to me that not all the information is in question. - Igor

1 answer 1

Yes, it is quite. Floating-point operations can lead to losses. You can use BigDecimal :

 BigDecimal sum = new BigDecimal(0); while (thereIsNumbers()) { BigDecimal number = new BigDecimal(getNextNumberAsStringFromExcel()); sum = sum.add(number); } System.out.println(sum); 

When creating a BigDecimal it is important to pass a string to the constructor. If you pass there the representation of your line is already in the form of a double , then there may be errors.

A little about the error: https://habrahabr.ru/post/219595/

  • Yes it solved the problem! - Padawan
  • BigDecimal will probably eat memory yes? - Padawan
  • one
    @Padawan Specifically, more memory will be used than regular double . All internal variables that contain the BigDecimal state are described here. However, if your code works approximately as I described, then each iteration of the loop will create a new BigDecimal , and the old ones (if possible) will be assembled by the GC . And if you do not need to work with millions of such variables, then you have nothing to fear. And in general, the String -representation of the number, in fact, takes less) - selya