Dit artikel is een spiegelartikel van machinevertaling, klik hier om naar het oorspronkelijke artikel te gaan.

Bekijken: 17373|Antwoord: 0

[Bron] java.math.BigDecimal klasse

[Link kopiëren]
Geplaatst op 07-04-2015 14:53:05 | | |

Operationele klassen voor grote getallen worden in Java aangeboden, namelijk de java.math.BinInteger-klasse en de java.math.BigDecimal-klasse. Deze twee klassen worden gebruikt voor hoogprecisie-berekeningen, waarbij de BigInteger-klasse de verwerkingsklasse is voor grote gehele getallen en de BigDecimal-klasse de verwerkingsklasse voor grote en kleine getallen. Hieronder introduceren we de BigDecimal-klasse:
De implementatie van BigDecimal maakt gebruik van BigInteger, behalve dat BigDecimal het concept van decimalen toevoegt. Algemene float- en dubbeltypegegevens kunnen alleen worden gebruikt voor wetenschappelijke of technische berekeningen, omdat in commerciële computing de vereiste numerieke nauwkeurigheid relatief hoog is, dus wordt de java.math.BigDecimal-klasse gebruikt, die elke precisie van vaste punten ondersteunt en kan worden gebruikt om valutawaarden nauwkeurig te berekenen. Hieronder introduceren we kort het gebruik ervan met voorbeelden

java.math.BigDecimal

Vandaag heb ik een programma geschreven over binaire en decimale conversie met verwijzing naar het leerboek, en het programma-algoritme is niet moeilijk, maar na het schrijven ontdekte ik dat, of het nu 2 tot 10 of 10 tot 2 is, het geen goede conversie is voor getallen groter dan 2,1 miljard, dat wil zeggen meer dan het gehele getal. 0 wordt.
Naslagwerken hebben vastgesteld dat het gebruik van BigInteger dit probleem oplost.
Dus heb ik de JDK opgezocht, het meerdere keren getest en uiteindelijk succesvol geschreven!
De gebruikservaring is als volgt:

1. BigInteger behoort tot java.math.BigInteger, dus importeer deze klasse voor elk gebruik. Af en toe vergat ik aan het begin te importeren, waardoor de prompt niet meer te vinden is in de constante prompt.

2. Er zijn veel bouwmethoden, maar tegenwoordig worden ze af en toe gebruikt:
BigInteger(String val)
          Zet de decimale stringrepresentatie van BigInteger om naar BigInteger.
BigInteger(String val, int radix)
          Zet de stringrepresentatie van het BigInteger om voor de gespecificeerde kardinaliteit naar het BigInteger.
Om 2 van het int type om te zetten naar BigInteger-type, schrijf je BigInteger two=new BigInteger("2"); Noot 2: dubbele aanhalingstekens mogen niet worden weggelaten

3. De BigInteger-klasse simuleert alle int-type wiskundige bewerkingen, zoals add()=="+", divide()="-", enzovoort, maar let op dat de inhoud niet direct kan worden gebruikt voor wiskundige bewerkingen bij het uitvoeren van wiskundige bewerkingen, en dat deze interne methoden moet gebruiken. En de operand moet ook van het type BigInteger zijn.
Bijvoorbeeld: two.add(2) is een onjuiste bewerking omdat 2 geen BigInteger-type wordt.

4. Wanneer je de berekeningsresultaten wilt uitvoeren, moet je de .toString-methode gebruiken om deze om te zetten in een decimale string, zo gedetailleerd als volgt:
String toString()
          Geeft de decimale stringrepresentatie van deze BigInteger terug.
Uitvoermethode: System.out.print(two.toString());

5. Leg de drie gebruikte functies uit.   
BigInteger rest(BigInteger val)
          Geeft een BigInteger terug met een waarde van (dit % val).
BigInteger negate()
          BigInteger geeft een waarde van (-dit) terug.
int compareTo(BigInteger val)
          Vergelijk dit BigInteger met het gespecificeerde BigInteger.
Restderis gebruikt om de rest te vinden.
Negate verandert de operand in het tegenovergestelde.
Compare wordt als volgt in detail uitgelegd:
vergelijkTo

publieke int compareTo(BigInteger val)

    Vergelijk dit BigInteger met het gespecificeerde BigInteger. Deze methode wordt geprefereerd voor elk van de zes Booleaanse vergelijkingsoperatoren (<, ==, >, >=, !=, <=). De voorgestelde uitspraak om deze vergelijkingen uit te voeren is: (x.compareTo(y) <op> 0), waarbij <op> een van de zes vergelijkingsoperatoren is.

     

    Specificatie:
        <BigInteger> interface Vergelijkbaar

    Parameters:
        val - Het BigInteger dat dit BigInteger daarmee vergelijkt.
    Terug:

   
  Titel Implementatie van precieze berekeningen van drijfkommagetallen in Java AYellow (Origineel) Modificatie           
  Trefwoorden Java floating point-getal nauwkeurige berekening         
   
   
  Vraag gesteld:   
  Wat zouden we zien als we het volgende programma compileren en draaien?   
  publieke klasse Test{   
          publieke statische 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);   
          }   
  };   
   
  Je leest het goed! Het resultaat is inderdaad   
  0.060000000000000005   
  0.5800000000000001   
  401.49999999999994   
  1.2329999999999999   
   
  Eenvoudige float- en double types in Java kunnen niet worden gebruikt. Dit probleem komt niet alleen voor in Java, maar ook in veel andere programmeertalen. In de meeste gevallen zijn de berekeningen nauwkeurig, maar je kunt het nog een paar keer proberen (je kunt een lus maken) om fouten zoals hierboven te doen. Nu begrijp ik eindelijk waarom er een BCD-code is.   
  Dit probleem is behoorlijk ernstig: als je 9,99999999999999999999999 yuan hebt, denkt je computer niet dat je 10 yuan aan goederen kunt kopen.   
  Sommige programmeertalen bieden gespecialiseerde valutatypes om deze situatie aan te kunnen, maar Java niet. Laten we nu eens kijken hoe we dit kunnen oplossen.   
   
      
   
  Afronding   
  Onze eerste reactie is ronden. De ronde methode in de wiskundeles kan niet worden ingesteld om een paar decimalen te behouden, we kunnen alleen dit doen (twee plaatsen behouden):   
  publieke dubbele ronde(dubbele waarde){   
          return Math.round(waarde*100)/100.0;   
  }   
   
  Helaas werkt bovenstaande code niet; als je 4.015 naar deze methode stuurt, krijg je 4.01 terug in plaats van 4.02, zoals we hierboven zagen.   
  4.015*100=401.4999999999999994   
  Daarom kunnen we, als we nauwkeurige afronding willen doen, geen eenvoudige types gebruiken om bewerkingen uit te voeren   
  java.text.DecimalFormat lost dit probleem ook niet op:   
  System.out.println(nieuwe java.text.DecimalFormat("0.00").format(4.025));   
  De output is 4,02   
   
      
   
  BigDecimal   
  Dit principe wordt ook genoemd in het boek "Effective Java"; float en double kunnen alleen worden gebruikt voor wetenschappelijke of technische berekeningen, en in business computing moeten we java.math.BigDecimal gebruiken. Er zijn 4 manieren om BigDecimal te bouwen, we geven niet om de twee die met BigInteger zijn gemaakt, dus zijn er nog twee, namelijk:   
  BigDecimal (dubbele val)     
                      Vertaalt een dubbel naar een BigDecimal.     
  BigDecimal (Snaarval)     
                      Vertaalt de String-repre-senatie van een BigDecimal naar een BigDecimal.   
   
  De API wordt kort beschreven en is meestal gemakkelijker te gebruiken. We kunnen het gebruiken zonder er zelfs maar over na te denken, wat zal het probleem zijn? Toen er iets misging, ontdekte ik dat er zo'n alinea in de gedetailleerde beschrijving stond van welke van bovenstaande methoden voldoende was:   
  Let op: de resultaten van deze constructor kunnen enigszins onvoorspelbaar zijn.   Men zou kunnen aannemen dat de nieuwe BigDecimal(.1) exact gelijk is aan .1, maar het is eigenlijk gelijk aan .1000000000000000055511151231257827021181583404541015625.   Dit is zo omdat 0,1 niet exact als een dubbel kan worden weergegeven (of, wat dat betreft, als een binaire breuk van een eindige lengte).   Dus de lange waarde die aan de constructor wordt doorgegeven is niet exact gelijk aan .1, ongeacht de schijn.     
  De (String)-constructor daarentegen is perfect voorspelbaar: nieuwe BigDecimal(".1") is precies gelijk aan .1, zoals te verwachten is.   Daarom wordt over het algemeen aanbevolen om de (String)constructor te gebruiken in plaats van deze.   
   
  Het blijkt dat als we nauwkeurig moeten berekenen, we String moeten gebruiken om BigDecimal te maken! Het voorbeeld in het boek Effective Java gebruikt String om BigDecimal te maken, maar het boek benadrukt dit niet, wat een kleine fout kan zijn.   
      
   
  Oplossing   
  Nu we dit probleem hebben opgelost, is het principe om BigDecimal te gebruiken en ervoor te zorgen dat je String gebruikt.   
  Maar stel je voor dat we een optellingsoperatie willen uitvoeren, eerst twee floating-point getallen moeten omzetten naar String, dan een BigDecimal maken, de optelmethode op één van hen aanroepen, het andere als argument doorgeven, en vervolgens het resultaat van de bewerking (BigDecimal) omzetten naar een floating-point getal. Kun je zo'n saai proces verdragen? Hieronder geven we een toolklasse Arith om de bewerking te vereenvoudigen. Het biedt de volgende statische methoden, waaronder optellen, aftrekken, vermenigvuldigen en delen, en afronden:   
  publieke statische dubbele addering (dubbele v1, dubbele v2)   
  publieke statische dubbele sub (dubbele v1, dubbele v2)   
  Publieke statische dubbele MUL (dubbele v1, dubbele v2)   
  Publieke statische dubbele div (dubbele v1, dubbele v2)   
  Publieke statische dubbele div (dubbele v1, dubbele v2, int-schaal)   
  Publieke statische dubbele ronde (dubbele V, Int Scale)   
   
   
   
  Bijlage   
   
   
  Bronbestand Arith.java:   
   
  import java.math.BigDecimal;   
  /**   
    * Omdat de eenvoudige types van Java geen floating-point-bewerkingen nauwkeurig kunnen uitvoeren, biedt deze gereedschapsklasse fijne mogelijkheden   
    * Exacte floating-point-operaties, waaronder optellen, aftrekken, vermenigvuldigen, delen en afronden.   
    */   
   
  publieke klasse Arith{   
   
          Standaard nauwkeurigheid van delingsoperaties   
          privé statische eindint DEF_DIV_SCALE = 10;   
   
   
          Deze klasse kan niet worden geïnstantieerd   
          privé Arith(){   
          }   
   
      
          /**   
            * Biedt precieze opteloperaties.   
            * @param v1 wordt toegevoegd   
            * @param v2 toevoeging   
            * @return De som van de twee parameters   
            */   
   
          publieke statische dubbele add(double v1,double v2){   
                  BigDecimal b1 = nieuwe BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nieuwe BigDecimal(Double.toString(v2));   
                  return b1.add(b2).doubleValue();   
          }   
   
          /**   
            * Biedt nauwkeurige aftrekoperaties.   
            * @param v1 wordt afgetrokken   
            * @param v2 min   
            * @return Het verschil tussen de twee parameters   
            */   
   
          publieke statische dubbele sub(dubbele v1,dubbele v2){   
                  BigDecimal b1 = nieuwe BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nieuwe BigDecimal(Double.toString(v2));   
                  return b1.subtract(b2).doubleValue();   
          }     
   
          /**   
            * Biedt precieze vermenigvuldigingsbewerkingen.   
            * @param v1 wordt vermenigvuldigd   
            * @param v2 vermenigvuldiger   
            * @return Het product van de twee parameters   
            */   
   
          publieke statische dubbele mul(dubbele v1,dubbele v2){   
                  BigDecimal b1 = nieuwe BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nieuwe BigDecimal(Double.toString(v2));   
                  return b1.multipliply(b2).doubleValue();   
          }   
   
      
   
          /**   
            * Biedt (relatief) nauwkeurige delingsoperaties wanneer onuitputtelijke deling plaatsvindt   
            * 10 decimalen en de volgende cijfers worden afgerond.   
            * @param v1 wordt gedeeld   
            * @param v2 divisor   
            * @return Het quotiënt van de twee parameters   
            */   
   
          publieke statische dubbele div(dubbele v1,dubbele v2){   
                  return div(v1,v2,DEF_DIV_SCALE);   
          }   
   
      
   
          /**   
            * Biedt (relatief) nauwkeurige divisie-operaties. Wanneer een onuitputtelijke situatie zich voordoet, wordt dit aangegeven door de schaalparameter   
            * Bepaal de nauwkeurigheid, en de getallen daarna worden afgerond.   
            * @param v1 wordt gedeeld   
            * @param v2 divisor   
            * @param toonladder geeft aan dat het nauwkeurig moet zijn tot op enkele decimalen.   
            * @return Het quotiënt van de twee parameters   
            */   
   
          publieke statische dubbele div(dubbele v1,dubbele v2,int-schaal){   
                  if(scale<0){   
                          gooi nieuwe IllegalArgumentException(   
                                  "De schaal moet een positief geheel getal of nul zijn");   
                  }   
                  BigDecimal b1 = nieuwe BigDecimal(Double.toString(v1));   
                  BigDecimal b2 = nieuwe BigDecimal(Double.toString(v2));   
                  return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
   
      
   
          /**   
            * Geeft precieze decimale afronding.   
            * @param v vereist afrondingsgetallen   
            * @param toonladder wordt gereserveerd na het decimale teken   
            * @return Afgeronde resultaten   
            */   
   
          publieke statische dubbele ronde (dubbele v,int schaal){   
                  if(scale<0){   
                          gooi nieuwe IllegalArgumentException(   
                                  "De schaal moet een positief geheel getal of nul zijn");   
                  }   
                  BigDecimal b = nieuwe BigDecimal(Double.toString(v));   
                  BigDecimal one = nieuwe BigDecimal ("1");   
                  return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
  };




Vorig:Het is het beste om geen string met betekenis als primaire sleutel te zetten
Volgend:VERSCHILLEN EN CONNECTIES TUSSEN JDK, JRE, JVM
Disclaimer:
Alle software, programmeermaterialen of artikelen die door Code Farmer Network worden gepubliceerd, zijn uitsluitend bedoeld voor leer- en onderzoeksdoeleinden; De bovenstaande inhoud mag niet worden gebruikt voor commerciële of illegale doeleinden, anders dragen gebruikers alle gevolgen. De informatie op deze site komt van het internet, en auteursrechtconflicten hebben niets met deze site te maken. Je moet bovenstaande inhoud volledig van je computer verwijderen binnen 24 uur na het downloaden. Als je het programma leuk vindt, steun dan de echte software, koop registratie en krijg betere echte diensten. Als er sprake is van een inbreuk, neem dan contact met ons op via e-mail.

Mail To:help@itsvse.com