Вопрос
У меня есть CSV-файл, где поля суммы и количества присутствуют в каждой подробной записи, за исключением заголовка и записи трейлера.Запись прицепа содержит значения общей стоимости , которые представляют собой общую сумму количества , умноженную на поле сумма в подробных записях .Мне нужно проверить, равно ли значение общей стоимости прицепа моему расчетному значению в полях сумма и количество.Я использую двойной тип данных для всех этих вычислений.Когда я просмотрел, я смог понять из приведенной ниже веб-ссылки, что это может создать проблему с использованием двойного типа данных при сравнении с десятичными точками.Это предполагает использование BigDecimal
http://epramono.blogspot.com/2005/01/double-vs-bigdecimal.html
Возникнут ли у меня проблемы, если я использую двойной тип данных.Как я могу выполнить вычисления, используя BigDecimal.Также я не уверен, сколько цифр я получу после десятичных знаков в CSV-файле.Также сумма может иметь положительное или отрицательное значение.
В CSV-файле
H, ABC....."D",....,"1","12.23" "D",.....,"3","-13.334" "D",......,"2","12" T, csd, 123,12.345
------------------------------ Во время проверки у меня появляется приведенный ниже код --------------------
double detChargeCount =0;
//From csv file i am reading trailer records charge value
String totChargeValue = items[3].replaceAll("\"","").trim();
if (null != totChargeValue && !totChargeValue.equals("")) {
detChargeCount = new Double(totChargeValue).doubleValue();
if(detChargeCount==calChargeCount)
validflag=true;
-----------------------При чтении CSV-файла у меня появляется приведенный ниже код
if (null != chargeQuan && !chargeQuan.equals("")) {
tmpChargeQuan=Long(chargeQuan).longValue();
}
if (null != chargeAmount && !chargeAmount.equals("")) {
tmpChargeAmt=new Double(chargeAmount).doubleValue();
calChargeCount=calChargeCount+(tmpChargeQuan*tmpChargeAmt);
}
I had declared the variables tmpChargeQuan, tmpChargeAmt, calChargeCount as double
Решение
Особенно для всего, что связано с финансовыми данными, но в целом для всего, что связано с читаемыми человеком числами, BigDecimal - это то, что вы хотите использовать вместо double, как указано в этом источнике.
В Документация на BigDecimal
это довольно прямолинейно и должно обеспечить все, что вам нужно.
Он имеет конструкторы int, double и string, так что вы можете просто иметь:
BigDecimal detChargeCount = new BigDecimal(0);
...
detChargeCount = new BigDecimal(totChargeValue);
Операторы реализованы как функции, поэтому вам придется делать такие вещи, как
tmpChargeQuan.multiply(tmpChargeAmt)
вместо того, чтобы просто tmpChargeQun * tmpChargeAmt
, но это не должно иметь большого значения.
но все они также определены со всеми перегрузками, которые вам могут понадобиться.
Другие советы
Очень возможно, что у вас возникнут проблемы с удвоениями, под которыми я подразумеваю, что предварительно вычисленное значение и вновь вычисленное значение могут отличаться на 0,000001 или меньше.
Если вы не знаете, как было вычислено значение, с которым вы сравниваете, я думаю, что лучшим решением является определение "равно" как имеющего разницу меньше, чем epsilon , где epsilon - это очень маленькое число, такое как .0001.
То есть.вместо того, чтобы использовать тест A == B
, использовать abs(A - B) < .0001
.