Тази статия е огледална статия за машинен превод, моля, кликнете тук, за да преминете към оригиналната статия.

Изглед: 17373|Отговор: 0

[Източник] java.math.BigDecimal клас

[Копирай линк]
Публикувано в 7.04.2015 г. 14:53:05 ч. | | |

Класове операции за големи числа са предоставени в java, а именно класът java.math.BinInteger и класът java.math.BigDecimal. Тези два класа се използват за високопрецизни изчисления, като класът BigInteger е класът за обработка за големи цели числа, а класът BigDecimal е класът за обработка за големи и малки числа. По-долу представяме класа BigDecimal:
Имплементацията на BigDecimal използва BigInteger, с изключение на това, че BigDecimal добавя концепцията за десетични числа. Общи float и double type данни могат да се използват само за научни или инженерни изчисления, тъй като в търговските изчисления изискваната числова точност е сравнително висока, затова се използва класът java.math.BigDecimal, който поддържа всяка прецизност на фиксирани точки и може да се използва за точно изчисляване на стойности на валутата. По-долу ще представим накратко употребата му с примери

java.math.BigDecimal

Днес написах програма за двоична и десетична преобразуване с препратка към учебника, и алгоритъмът не е труден, но след като написах, установих, че независимо дали е 2 до 10 или 10 към 2, това не е добро преобразуване за числа над 2.1 милиарда, тоест повече от цяло число. ще стане 0.
Справочници са установили, че използването на BigInteger решава този проблем.
Затова потърсих JDK, тествах го няколко пъти и накрая го написах успешно!
Опитът при използване е следният:

1. BigInteger принадлежи към java.math.BigInteger, така че импортирайте този клас преди всяка употреба. Понякога забравях да импортирам в началото, така че подсказката не може да се намери в постоянния подсказ.

2. Съществуват много методи за строителство, но сега те се използват от време на време:
BigInteger(String val)
          Преобразуване на десетичното представяне на BigInteger в BigInteger.
BigInteger(String val, int radix)
          Преобразува представянето на низовете на BigInteger за зададената кардиналност в BigInteger.
За да преобразувате 2 от int тип в BigInteger тип, запишете BigInteger two=нов BigInteg("2"); Забележка: 2: двойни кавички не могат да бъдат пропуснати

3. Класът BigInteger симулира всички int-тип математически операции, като add()=="+", divide()=="-" и др., но имайте предвид, че съдържанието му не може да се използва директно за математически операции при изпълнение на математически операции и трябва да използва вътрешните му методи. А операнда му също трябва да е от тип BigInteg.
Например: two.add(2) е неправилна операция, защото 2 не става тип BigInteger.

4. Когато искате да изведете резултатите от изчислението, трябва да използвате метода .toString, за да го преобразувате в десетичен низ, както е описано както следва:
String toString()
          Връща десетичното представяне на този BigInteg.
Метод на изход: System.out.print(two.toString());

5. Обяснете трите използвани функции.   
BigInteger remainder(BigInteger val)
          Връща BigInteger със стойност (този % val).
BigInteger negate()
          BigInteger връща стойност на (-това).
int compareTo(BigInteger val)
          Сравнете този BigInteger с посочения BigInteger.
Остатъкът се използва за намиране на остатъка.
Negate превръща операнда в противоположност.
Сравнението е обяснено подробно по следния начин:
сравни с

public int compareTo(BigInteger val)

    Сравнете този BigInteger с посочения BigInteger. Този метод е предпочитан за всеки от шестте булеви оператора за сравнение (<, ==, >, >=, !=, <=). Предложеното твърдение за извършване на тези сравнения е: (x.compareTo(y) <op> 0), където е <op> един от шестте оператора за сравнение.

     

    Спецификатор:
        <BigInteger> интерфейс Сравним

    Параметри:
        val - Голямото цяло число, което сравнява този BigInteger с него.
    Назад:

   
  Заглавие Реализиране на прецизни изчисления на числа с плаваща запетая в Java AYellow (оригинална) модификация           
  Ключови думи Java плаваща запетая, прецизно изчисление         
   
   
  Зададен въпрос:   
  Какво бихме видели, ако компилираме и пуснем следната програма?   
  публичен клас тест{   
          public static void main(String args[]){   
                  System.out.println(0.05+0.01);   
                  System.out.println(1.0-0.42);   
                  System.out.println(4.015*100);   
                  System.out.println(123.3/100);   
          }   
  };   
   
  Прочетохте правилно! Резултатът наистина е   
  0.060000000000000005   
  0.5800000000000001   
  401.49999999999994   
  1.2329999999999999   
   
  Прости float и double типове в Java не могат да се оперират. Този проблем не се среща само в Java, но и в много други програмни езици. В повечето случаи изчисленията са точни, но можеш да опиташ още няколко пъти (можеш да направиш цикъл), за да пробваш грешки като горната. Сега най-накрая разбирам защо има BCD код.   
  Този проблем е доста сериозен, ако имате 9.99999999999999999 юана, компютърът ви няма да мисли, че можете да купите 10 юана за стока.   
  Някои програмни езици предоставят специализирани типове валути за справяне с тази ситуация, но Java не го прави. Сега нека видим как да го оправим.   
   
      
   
  Закръгляне   
  Първата ни реакция е да направим заобикаляне. Методът на кръга в класа по математика не може да бъде настроен да поддържа няколко десетични числа, можем да направим само това (да запазим две места):   
  Публичен двоен кръг (двойна стойност){   
          return Math.round(value*100)/100.0;   
  }   
   
  За съжаление, горният код не работи, предаването на 4.015 към този метод ще върне 4.01 вместо 4.02, както видяхме по-горе   
  4.015*100=401.4999999999999   
  Следователно, ако искаме да правим точно закръгляне, не можем да използваме прости типове за извършване на операции   
  java.text.DecimalFormat също не решава този проблем:   
  System.out.println(new java.text.DecimalFormat("0.00").format(4.025));   
  Изходът е 4.02   
   
      
   
  BigDecimal   
  Този принцип е споменат и в книгата "Effective Java", float и double могат да се използват само за научни или инженерни изчисления, а в бизнес изчисленията трябва да използваме java.math.BigDecimal. Има 4 начина за изграждане на BigDecimal, не ни интересуват двата, които се правят с BigInteger, затова има още два, които са:   
  BigDecimal (двойна вал)     
                      Превежда двойно в BigDecimal.     
  BigDecimal (String val)     
                      Превежда репрезентацията на String на BigDecimal в BigDecimal.   
   
  API е описан накратко и обикновено е по-лесен за използване. Може да го използваме без дори да се замисляме, какъв ще е проблемът? Когато нещо се обърка, разбрах, че в подробното описание на това кой от горните методи е достатъчен, има такъв абзац:   
  Забележка: резултатите от този конструктор могат да бъдат донякъде непредсказуеми.   Може да се предположи, че новият BigDecimal(.1) е точно равен на .1, но всъщност е равен на .1000000000000000055511151231257827021181583404541015625.   Това е така, защото .1 не може да бъде представено точно като двойник (или, за този въпрос, като двоична дроб на всяка крайна дължина).   Следователно, дългата стойност, която се предава на конструктора, не е точно равна на 0.1, независимо от видимостта.     
  Конструкторът (String), от друга страна, е напълно предсказуем: новият BigDecimal(".1") е точно равен на .1, както се очаква.   Затова обикновено се препоръчва конструкторът (String) да се използва вместо този.   
   
  Оказва се, че ако трябва да изчисляваме точно, трябва да използваме String, за да създадем BigDecimal! Примерът в книгата Effective Java използва String за създаване на BigDecimal, но книгата не подчертава това, което може да е малка грешка.   
      
   
  Решение   
  Сега, след като решихме този проблем, принципът е да използваме BigDecimal и да се уверим, че се използва String.   
  Но представете си, че ако искаме да извършим операция за събиране, първо трябва да преобразуваме две числа с плаваща запетая в String, след това да създадем BigDecimal, да извикаме метода за събиране на едното от тях, да подадем другото като аргумент и след това да преобразуваме резултата от операцията (BigDecimal) в число с плаваща запетая. Можеш ли да издържиш толкова досаден процес? По-долу предоставяме клас инструмент Arith, за да опростим операцията. Тя предлага следните статични методи, включително събиране, изваждане, умножение и делене, както и закръгляне:   
  Публично статично двойно събиране (двойно v1, двойно v2)   
  Публичен статичен двоен суб (Double V1, Double V2)   
  Публично статично двойно MUL (двойно V1, двойно v2)   
  Публичен статичен двоен дивизион (двойно V1, двойно v2)   
  Публичен статичен двоен дивизион (двойно v1, двойно v2, интелект скала)   
  Публичен статичен двоен кръг (двойна V, Int скала)   
   
   
   
  Приложение   
   
   
  Изходен файл Arith.java:   
   
  import java.math.BigDecimal;   
  /**   
    * Тъй като простите типове на Java не могат точно да изпълняват операции с плаваща запетая, този клас инструмент предоставя фини   
    * Точни операции с плаваща запетая, включително събиране, изваждане, умножение, деление и закръгляне.   
    */   
   
  публична класа Arith{   
   
          Стандартна точност при деление   
          частен статичен финален интелект DEF_DIV_SCALE = 10;   
   
   
          Този клас не може да бъде инстанциран   
          private Arith(){   
          }   
   
      
          /**   
            * Осигурява прецизни операции по събиране.   
            * @param v1 се добавя   
            * @param добавяне във v2   
            * @return Сумата от двата параметъра   
            */   
   
          Публично статично двойно събиране(двойно v1,двойно v2){   
                  BigDecimal b1 = нов BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = нов BigDecimal(Double.toString(v2));   
                  return b1.add(b2).doubleValue();   
          }   
   
          /**   
            * Осигурява прецизни операции по изваждане.   
            * @param v1 се изважда   
            * @param v2 минус   
            * @return Разликата между двата параметъра   
            */   
   
          Публичен статичен двоен суб (Double V1,Double V2){   
                  BigDecimal b1 = нов BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = нов BigDecimal(Double.toString(v2));   
                  return b1.subtract(b2).doubleValue();   
          }     
   
          /**   
            * Осигурява прецизни операции за умножение.   
            * @param v1 се умножава   
            * @param множител v2   
            * @return Произведението на двата параметъра   
            */   
   
          Публичен статичен двоен mul(double v1,double v2){   
                  BigDecimal b1 = нов BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = нов BigDecimal(Double.toString(v2));   
                  return b1.multiply(b2).doubleValue();   
          }   
   
      
   
          /**   
            * Осигурява (относително) точни операции по деление, когато настъпи неизчерпаемо деление   
            * 10 десетични знака и следващите цифри са закръглени.   
            * @param v1 е разделен   
            * @param v2 divisor   
            * @return Факторът на двата параметъра   
            */   
   
          Публичен статичен двоен div(double v1,double v2){   
                  return div(v1,v2,DEF_DIV_SCALE);   
          }   
   
      
   
          /**   
            * Осигурява (относително) точни операции по деление. Когато възникне неизчерпаема ситуация, тя се показва от параметъра на мащаба   
            * Определете точността и числата след нея ще бъдат закръглени.   
            * @param v1 е разделен   
            * @param v2 divisor   
            * @param скала показва, че трябва да е точна до няколко десетични знака.   
            * @return Факторът на двата параметъра   
            */   
   
          Публичен статичен двоен div(double v1, double v2,int scale){   
                  if(scale<0){   
                          хвърли нов IllegalArgumentException(   
                                  "Скалата трябва да е положително цяло число или нула");   
                  }   
                  BigDecimal b1 = нов BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = нов BigDecimal(Double.toString(v2));   
                  return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
   
      
   
          /**   
            * Осигурява прецизно закръгляне на десетичната зала.   
            * @param v изисква закръгляне на числата   
            * @param скала се запазва след десетичната точка   
            * @return Закръглени резултати   
            */   
   
          Публичен статичен двоен рунд(двойно V,int мащаб){   
                  if(scale<0){   
                          хвърли нов IllegalArgumentException(   
                                  "Скалата трябва да е положително цяло число или нула");   
                  }   
                  BigDecimal b = нов BigDecimal(Double.toString(v));   
                  BigDecimal one = нов BigDecimal("1");   
                  return b.divide(едно, scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
  };




Предишен:Най-добре е да не се задава низ, чиято значение е първична тоналност
Следващ:JDK, JRE, JVM разлики и връзки
Отричане:
Целият софтуер, програмни материали или статии, публикувани от Code Farmer Network, са само за учебни и изследователски цели; Горното съдържание не трябва да се използва за търговски или незаконни цели, в противен случай потребителите ще понесат всички последствия. Информацията на този сайт идва от интернет, а споровете за авторски права нямат нищо общо с този сайт. Трябва напълно да изтриете горното съдържание от компютъра си в рамките на 24 часа след изтеглянето. Ако ви харесва програмата, моля, подкрепете оригинален софтуер, купете регистрация и получете по-добри услуги. Ако има нарушение, моля, свържете се с нас по имейл.

Mail To:help@itsvse.com