Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 17373|Odpowiedź: 0

[Źródło] java.math.BigDecimal class

[Skopiuj link]
Opublikowano 07.04.2015 14:53:05 | | |

W Javie dostępne są klasy operacji dla dużych liczb, mianowicie java.math.BinInteger oraz java.math.BigDecimal. Te dwie klasy są używane w obliczeniach o wysokiej precyzji, przy czym klasa BigInteger jest klasą przetwarzania dla dużych liczb całkowitych, a klasa BigDecimal to klasa przetwarzania dla dużych i małych liczb. Poniżej przedstawiamy klasę BigDecimal:
Implementacja BigDecimal wykorzystuje BigInteger, z tą różnicą, że BigDecimal dodaje koncepcję liczb przecinkowych. Ogólne dane typu float i double type mogą być używane tylko do obliczeń naukowych lub inżynierskich, ponieważ w informatyce komercyjnej wymagana dokładność numeryczna jest stosunkowo wysoka, dlatego używa się klasy java.math.BigDecimal, która obsługuje dowolną precyzję punktów stałych i może być użyta do dokładnego obliczania wartości walutowych. Poniżej krótko przedstawimy jego użycie z przykładami

java.math.BigDecimal

Dziś napisałem program o konwersji binarnej i dziesiętnej z odniesieniem do podręcznika, i algorytm programu nie jest trudny, ale po napisaniu odkryłem, że niezależnie od tego, czy jest to 2 do 10, czy 10 do 2, nie jest to dobra konwersja dla liczb większych niż 2,1 miliarda, czyli więcej niż zakres całkowity. stanie się 0.
Książki referencyjne wykazały, że użycie BigInteger rozwiązuje ten problem.
Więc sprawdziłem JDK, przetestowałem go kilka razy i w końcu napisałem go pomyślnie!
Doświadczenie użytkowania wygląda następująco:

1. BigInteger należy do java.math.BigInteger, więc importuj tę klasę przed każdym użyciem. Czasami zapominałem zaimportować na początku, więc prompt nie pojawia się w stałym promptie.

2. Istnieje wiele metod konstrukcyjnych, ale obecnie są one okazjonalnie stosowane:
BigInteger(wartość ciągów łańcuchowych)
          Przekonwertuj reprezentację ciągu dziesiętnego BigInteger na BigInteger.
BigInteger(wartość ciągu ciągów, int radix)
          Konwertuje reprezentację ciągu BigInteger dla określonej liczebności na BigInteger.
Aby przekonwertować 2 typu int na typ BigInteger, zapisz BigInteger two=new BigInteger("2"); Uwaga 2: podwójnych cudzysłowów nie można pominąć

3. Klasa BigInteger symuluje wszystkie operacje matematyczne typu int, takie jak add()=="+", didele()=="-" itd., ale należy zauważyć, że jej zawartość nie może być bezpośrednio wykorzystywana do operacji matematycznych podczas wykonywania operacji matematycznych i musi stosować metody wewnętrzne. A jego operand musi również mieć typ BigInteger.
Na przykład: operacja two.add(2) jest nieprawidłową, ponieważ 2 nie staje się typem BigInteger.

4. Gdy chcesz wypisać wyniki obliczeń, powinieneś użyć metody .toString do przekształcenia ich w ciąg dziesiętny, zgodnie z następującymi szczegółami:
String toString()
          Zwraca reprezentację ciągu dziesiętnego tej BigInteger.
Metoda wyjścia: System.out.print(two.toString());

5. Wyjaśnij trzy używane funkcje.   
BigInteger reszta (BigInteger val)
          Zwraca BigInteger o wartości (tej wartości procentowej).
BigInteger negate()
          BigInteger zwraca wartość (-this).
int compareTo(BigInteger val)
          Porównaj tę BigInteger z podaną BigInteger.
reszta używana do znalezienia reszty.
Negatuj zamienia operand w przeciwieństwo.
Porównanie jest szczegółowo wyjaśnione następująco:
compareTo

public int compareTo(BigInteger val)

    Porównaj tę BigInteger z podaną BigInteger. Metoda ta jest preferowana dla każdego z sześciu operatorów porównania boolowskiego (<, ==, >, >=, !=, <=). Sugerowane stwierdzenie do wykonania tych porównań to: (x.compareTo(y) <op> 0), gdzie jest <op> jednym z sześciu operatorów porównania.

     

    Specyfikator:
        interfejs<BigInteger> porównywalny

    Parametry:
        val – WielkaCałkowita liczba, która porównuje tę Wielką Liczbę do niej.
    Wstecz:

   
  Tytuł Implementacja precyzyjnych obliczeń liczb zmiennoprzecinkowych w Java Modyfikacja AYellow (oryginalna)           
  Słowa kluczowe Presyjne obliczenia liczby zmiennoprzecinkowej w Javie         
   
   
  Pytanie zadane:   
  Co byśmy zobaczyli, gdybyśmy skompilowali i uruchomili następujący program?   
  test klasy publicznej{   
          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);   
          }   
  };   
   
  Dobrze przeczytałeś! Efekt jest rzeczywiście   
  0.060000000000000005   
  0.5800000000000001   
  401.49999999999994   
  1.2329999999999999   
   
  Proste typy float i double w Javie nie mogą być obsługiwane. Ten problem występuje nie tylko w Javie, ale także w wielu innych językach programowania. W większości przypadków obliczenia są dokładne, ale możesz spróbować jeszcze kilka razy (można zrobić pętlę), żeby wypróbować błędy takie jak ten powyżej. Teraz w końcu rozumiem, dlaczego istnieje kod BCD.   
  Ten problem jest dość poważny – jeśli masz 9,999999999999999999 juanów, twój komputer nie pomyśli, że możesz kupić towary za 10 juanów.   
  Niektóre języki programowania oferują specjalistyczne typy walut do obsługi takich sytuacji, ale Java tego nie robi. Teraz zobaczmy, jak to naprawić.   
   
      
   
  Zaokrąglanie   
  Naszą pierwszą reakcją jest zaokrąglenie. Metoda zaokrąglenia w klasie matematyki nie może być ustawiona tak, by utrzymywać kilka miejsc po przecinku, możemy zrobić tylko to (zachować dwa miejsca):   
  publiczna podwójna runda (podwójna wartość){   
          return Math.round(value*100)/100.0;   
  }   
   
  Niestety, powyższy kod nie działa, przesłanie wersji 4.015 do tej metody zwróci 4.01 zamiast 4.02, jak widzieliśmy powyżej   
  4.015*100=401.49999999999999994   
  Dlatego jeśli chcemy wykonać dokładne zaokrąglenia, nie możemy używać prostych typów do wykonywania operacji   
  java.text.DecimalFormat również nie rozwiązuje tego problemu:   
  System.out.println(new java.text.DecimalFormat("0.00").format(4.025));   
  Wydajność wynosi 4,02   
   
      
   
  BigDecimal   
  Zasada ta jest również wspomniana w książce "Effective Java", gdzie float i double mogą być używane tylko do obliczeń naukowych lub inżynierskich, a w informatyce biznesowej musimy używać java.math.BigDecimal. Istnieją 4 sposoby na zbudowanie BigDecimal, nie obchodzi nas to, że dwa są stworzone w BigInteger, więc są jeszcze dwa kolejne, a mianowicie:   
  BigDecimal (podwójna wartości)     
                      Tłumaczy podwójne na BigDecimal.     
  BigDecimal (wartość ciągu ciągów)     
                      Tłumaczy powtarzanie ciągu BigDecimal na BigDecimal.   
   
  API jest krótko opisane i zazwyczaj łatwiejsze w obsłudze. Możemy go używać nawet nie myśląc, jaki będzie problem? Gdy coś poszło nie tak, odkryłem, że w szczegółowym opisie jest taki akapit, która z powyższych metod jest wystarczająca:   
  Uwaga: wyniki tego konstruktora mogą być dość nieprzewidywalne.   Można by założyć, że nowy BigDecimal(.1) jest dokładnie równy 0,1, ale w rzeczywistości jest równy 0,1000000000000000055511151231257827021181583404541015625.   Dzieje się tak, ponieważ 0,1 nie może być dokładnie reprezentowane jako podwójne (ani, co więcej, jako ułamek binarny dowolnej skończonej długości).   W związku z tym wartość długa przekazywana konstruktorowi nie jest dokładnie równa 0,1, pomijając pozory.     
  Konstruktor (String) natomiast jest doskonale przewidywalny: nowy BigDecimal(".1") jest dokładnie równy 0,1, jak można się spodziewać.   Dlatego ogólnie zaleca się, aby konstruktor (String) był preferowany przed tym.   
   
  Okazuje się, że jeśli musimy dokładnie liczyć, musimy użyć Stringu, aby stworzyć BigDecimal! Przykład z książki Effective Java używa String do tworzenia BigDecimal, ale książka tego nie podkreśla, co może być drobnym błędem.   
      
   
  Rozwiązanie   
  Teraz, gdy rozwiązaliśmy ten problem, zasada polega na użyciu BigDecimal i upewnienia się, że używa się String.   
  Wyobraź sobie, że jeśli chcemy wykonać operację dodawania, najpierw musimy przekonwertować dwie liczby zmiennoprzecinkowe na String, potem stworzyć BigDecimal, wywołać metodę dodawania na jednej z nich, przekazać drugą jako argument, a następnie przekonwertować wynik operacji (BigDecimal) na liczbę zmiennoprzecinkową. Czy dasz radę znieść tak żmudny proces? Poniżej przedstawiamy klasę narzędzi Arytm, aby uprościć operację. Oferuje następujące metody statyczne, w tym dodawanie, odejmowanie, mnożenie i dzielenie oraz zaokrąglanie:   
  publiczne statyczne podwójne dodawanie (podwójne v1, podwójne v2)   
  publiczna statyczna podwójna wersja subwooferowa (podwójna wersja 1, podwójna wersja 2)   
  publiczny statyczny double mul (double v1, double v2)   
  publiczna statyczna podwójna prezentacja (podwójna wersja 1, podwójna wersja 2)   
  publiczna statyczna podwójna rozdzielczość (podwójna wersja v1, podwójna v2, skala int)   
  publiczna statyczna podwójna runda (podwójne V, skala INT)   
   
   
   
  Aneks   
   
   
  Plik źródłowy Arith.java:   
   
  import java.math.BigDecimal;   
  /**   
    * Ponieważ proste typy Javy nie są w stanie dokładnie wykonywać operacji zmiennoprzecinkowych, ta klasa narzędzi zapewnia fines   
    * Dokładne operacje zmiennoprzecinkowe, w tym dodawanie, odejmowanie, mnożenie, dzielenie i zaokrąglanie.   
    */   
   
  Arytm klasy publicznej{   
   
          Domyślna dokładność operacji dzielenia   
          prywatny statyczny końcowy int DEF_DIV_SCALE = 10;   
   
   
          Tej klasy nie da się zinstancjonować   
          prywatny Arith(){   
          }   
   
      
          /**   
            * Zapewnia precyzyjne operacje dodawania.   
            * @param dodano v1   
            * @param dodawanie v2   
            * @return Suma dwóch parametrów   
            */   
   
          publiczne statyczne podwójne dodawanie(double v1,double v2){   
                  BigDecimal b1 = nowy BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nowy BigDecimal(Double.toString(v2));   
                  return b1.add(b2).doubleValue();   
          }   
   
          /**   
            * Zapewnia precyzyjne operacje odejmowania.   
            * @param v1 jest odejmowany   
            * @param v2 minus   
            * @return Różnica między tymi dwoma parametrami   
            */   
   
          publiczny statyczny podwójny sub(double v1,double v2){   
                  BigDecimal b1 = nowy BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nowy BigDecimal(Double.toString(v2));   
                  return b1.subtract(b2).doubleValue();   
          }     
   
          /**   
            * Zapewnia precyzyjne operacje mnożenia.   
            * @param v1 jest mnożone   
            * @param mnożnik v2   
            * @return Iloczyn obu parametrów   
            */   
   
          publiczny statyczny double mul(double v1,double v2){   
                  BigDecimal b1 = nowy BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nowy BigDecimal(Double.toString(v2));   
                  return b1.multiply(b2).doubleValue();   
          }   
   
      
   
          /**   
            * Zapewnia (stosunkowo) dokładne operacje podziału, gdy występuje niewyczerpany podział   
            * 10 miejsc po przecinku oraz następujące cyfry są zaokrąglone.   
            * @param v1 jest podzielony   
            * @param dzielnik v2   
            * @return Iloraz dwóch parametrów   
            */   
   
          publiczny statyczny double div(double v1,double v2){   
                  powrót (v1,v2,DEF_DIV_SCALE);   
          }   
   
      
   
          /**   
            * Zapewnia (stosunkowo) dokładne operacje dywizji. Gdy zachodzi niewyczerpana sytuacja, jest ona wskazana parametrem skali   
            * Określ dokładność, a liczby po niej zostaną zaokrąglone.   
            * @param v1 jest podzielony   
            * @param dzielnik v2   
            * @param skala wskazuje, że musi być dokładna co kilka miejsc po przecinku.   
            * @return Iloraz dwóch parametrów   
            */   
   
          publiczna statyczna podwójna div(podwójna wersja v1, podwójna v2, skala inteligencji){   
                  if(scale<0){   
                          throw new IllegalArgumentException(   
                                  "Skala musi być dodatnią liczbą całkowitą lub zerem");   
                  }   
                  BigDecimal b1 = nowy BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nowy BigDecimal(Double.toString(v2));   
                  return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
   
      
   
          /**   
            * Zapewnia precyzyjne zaokrąglanie dziesiętne.   
            * @param v wymaga zaokrąglenia liczb   
            * @param skala jest zarezerwowana po przecinku dziesiętnym   
            * @return Wyniki zaokrąglone   
            */   
   
          publiczna statyczna podwójna runda (podwójne V, skala INT){   
                  if(scale<0){   
                          throw new IllegalArgumentException(   
                                  "Skala musi być dodatnią liczbą całkowitą lub zerem");   
                  }   
                  BigDecimal b = nowy BigDecimal(Double.toString(v));   
                  BigDecimal One = nowy BigDecimal("1");   
                  return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
  };




Poprzedni:Najlepiej nie ustawiać ciągu z znaczeniem jako kluczem głównym
Następny:Różnice i powiązania między JDK, JRE, JVM
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com