Относительно большого десятичного числа - PullRequest
1 голос
/ 01 марта 2010

У меня есть CSV-файл, в котором поля количества и количества присутствуют в каждой подробной записи, кроме заголовка и записи трейлера. У записи трейлера есть общие значения сбора, которые являются общей суммой количества, умноженного на поле количества в подробных записях. Мне нужно проверить, равно ли значение полной оплаты прицепа моим расчетным значениям полей количества и количества. Я использую тип данных double для всех этих расчетов

В поле суммы файла CSV отображается как «10,12» или «10» или «10,0» или «10,456» или «10,4555» или «-10,12». Также сумма может иметь положительное или отрицательное значение.

В 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); 
                          } 

Я объявил переменные tmpChargeQuan, tmpChargeAmt, calChargeCount как двойные

Когда я искал в Интернете, я узнал, что double может создать проблемы для финансовых расчетов, поэтому нужно использовать BIGDECIMAL. Но мне интересно, этот сценарий применим для моего расчета. В моем случае значение суммы может иметь до 5 или 6 цифр после десятичной точки. «Могу ли я использовать двойной тип данных для этого вычисления? Я использую его для проверки. Будет ли это создавать проблему, если я использую приведенный выше код с умножением с использованием double?

Ответы [ 2 ]

4 голосов
/ 01 марта 2010

Я подробно остановлюсь на том, что Адел уже кратко ответила. Вы можете вписать эти числа в двойной тип данных. Проблема в том, что когда вычисляются числа, будут ли они рассчитаны правильно? Ответ - нет, они не будут. Как правило, это не такая большая проблема, если вы учитываете это с помощью дельты, т. Е. Ваша свобода в предположении, эквивалентно ли двойное значение другому двойному значению. Но для вычислений с точными числами, таких как денежные вычисления, вы должны использовать тип, такой как BigDecimal, для хранения значений.

Когда у вас есть этот номер: 1,23445 как двойной, это может выглядеть как 1.23445 но на самом деле это может быть что-то вроде 1,234450000003400345543034

Когда вы выполняете несколько вычислений для таких чисел, как правило, эти дополнительные места не имеют значения - однако со временем они будут давать неточные результаты. В BigDecimal, когда число указывается как его строковое представление, оно равно этому числу - оно не страдает от "почти такой же хорошей" проблемы, как двойные числа.

Я обновляю этот ответ, чтобы включить некоторые заметки из двойного конструктора BigDecimal, найденного по этому адресу .

Результаты этого конструктора могут быть несколько непредсказуемо. Можно Предположим, что написание нового BigDecimal (0.1) в Java создает BigDecimal, который точно равен 0,1 (немасштабированное значение 1 со шкалой 1), но на самом деле оно равно в 0,1000000000000000055511151231257827021181583404541015625. Это потому, что 0,1 не может быть представлен точно как двойной (или, в этом отношении, как двоичная дробь любой конечной длины). Таким образом, значение что передается в конструктор не совсем равен 0,1, несмотря на внешний вид.

Конструктор String, с другой стороны, вполне предсказуемы написание новых BigDecimal ("0.1") создает BigDecimal, который точно равен 0,1, как и следовало ожидать. Поэтому, как правило, рекомендуется Строковый конструктор будет использоваться в предпочтение этому.

Когда двойник должен быть использован в качестве источника для BigDecimal, обратите внимание, что это конструктор предоставляет точный преобразование; это не дает то же самое в результате преобразования двойного в Строка с использованием Double.toString (double) метод и затем с помощью BigDecimal (String) конструктор. Чтобы получить этот результат, используйте метод static valueOf (double).

2 голосов
/ 01 марта 2010

Дело не в размерах, а в точном выражении чисел с плавающей запятой. Как класс BigDecimal помогает Java получить правильную арифметику .

...