|
|
Postitatud 07.04.2015 14:53:05
|
|
|

Suurte arvude operatsiooniklassid on java-s esitatud, nimelt java.math.BinInteger klass ja java.math.BigDecimal klass. Neid kahte klassi kasutatakse kõrge täpsusega arvutuseks: BigInteger klass on suurte täisarvude töötlemisklass ja BigDecimal klass suurte ja väikeste arvude töötlemisklass. Allpool tutvustame BigDecimal klassi: BigDecimali rakendus kasutab BigIntegerit, kuid BigDecimal lisab kümnendarvude mõiste. Üldisi float- ja topelttüüpi andmeid saab kasutada ainult teaduslikes või inseneriarvutustes, sest kommertsarvutustes on nõutav numbriline täpsus suhteliselt kõrge, seega kasutatakse java.math.BigDecimal klassi, mis toetab fikseeritud punktide täpsust ja võimaldab valuuta väärtusi täpselt arvutada. Allpool tutvustame lühidalt selle kasutust näidetega
java.math.BigDecimal
Täna kirjutasin programmi binaar- ja kümnendsüsteemist viidates õpikule, ja programmi algoritm ei ole keeruline, kuid pärast kirjutamist leidsin, et olgu see 2 kuni 10 või 10 kuni 2, ei ole see hea teisendus arvudele, mis ületavad 2,1 miljardit, st rohkem kui täisarvuline vahemik. muutub nulliks. Viiteraamatud on leidnud, et BigInteger kasutamine lahendab selle probleemi. Nii et otsisin JDK üles, testisin seda mitu korda ja lõpuks kirjutasin selle edukalt! Kasutuskogemus on järgmine:
1. BigInteger kuulub java.math.BigIntegeri hulka, seega impordi see klass enne iga kasutust. Mõnikord unustasin alguses importida, nii et prompti ei leia pidevas käes.
2. Ehitusmeetodeid on palju, kuid nüüd kasutatakse neid aeg-ajalt: BigInteger (String val) Teisenda BigInteger'i kümnendkomaa stringi esitus BigIntegeriks. BigInteger (string val, int radix) Teisendab määratud kardinaalsuse BigIntarvu stringi esituse BigIntegeriks. Et teisendada 2 int tüüpi BigInteger tüübiks, kirjutage BigInteger kaks=uus Suur Täisarv ("2"); Märkus 2: topeltjutumärke ei tohi välja jätta
3. BigInteger klass simuleerib kõiki int-tüüpi matemaatilisi operatsioone, nagu add()=="+", divide()=="-" jne, kuid tuleb märkida, et selle sisu ei saa matemaatiliste operatsioonide puhul otseselt kasutada matemaatiliste operatsioonide tegemiseks ning peab kasutama sisemisi meetodeid. Ja selle operaator peab samuti olema tüüpi BigInteger. Näiteks: two.add(2) on vale operatsioon, sest 2 ei muutu BigInteger tüübiks.
4. Kui soovid arvutustulemusi välja anda, peaksid kasutama .toString meetodit, et teisendada see kümnendkomateks stringiks, mis on kirjeldatud järgmiselt: String toString() Tagastab selle BigIntegeri kümnendjärjestuse esituse. Väljundmeetod: System.out.print(two.toString());
5. Selgita kolme kasutatavat funktsiooni. BigInteger remainder (BigInteger val) Tagastab BigIntarvu, mille väärtus on (see % val). BigInteger negate() BigInteger tagastab väärtuseks (-see). int compareTo(BigInteger val) Võrdle seda BigIntear'i määratud BigInteger'iga. Remainderis kasutati ülejäänud leidmiseks. Negate muudab operendi vastupidiseks. Võrdlus on üksikasjalikult selgitatud järgmiselt: võrdle
public int compareTo(BigInteger val)
Võrdle seda BigIntear'i määratud BigInteger'iga. Seda meetodit eelistatakse iga kuue Boole'i võrdlusoperaatori puhul (<, ==, >, >=, !=, <=). Soovitatud väide nende võrdluste tegemiseks on: (x.compareTo(y) <op> 0), kus on <op> üks kuuest võrdlusoperaatorist.
Täpsustaja: Liides<BigInteger> võrreldav
Parameetrid: val – Suur Täisarv, mis võrdleb seda SuurTäisarvu sellega. Tagasi:
Pealkiri Täpsete ujukomaarvutuste rakendamine Java-s AYellow (originaal) modifikatsioon Märksõnad Java ujukomaarvude täpne arvutamine
Küsimus esitatud: Mida me näeksime, kui kompileeriksime ja käivitaksime järgmise programmi? public class Test{ 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); } };
Sa lugesid õigesti! Tulemus on tõepoolest 0.060000000000000005 0.5800000000000001 401.49999999999994 1.2329999999999999
Lihtsaid float- ja topelttüüpe Javas ei saa kasutada. See probleem esineb mitte ainult Javas, vaid ka paljudes teistes programmeerimiskeeltes. Enamasti on arvutused täpsed, kuid võid proovida veel paar korda (saad teha tsükli), et proovida selliseid vigu nagu eelpool. Nüüd saan lõpuks aru, miks BCD kood olemas on. See probleem on üsna tõsine, kui sul on 9,99999999999999999999999999999999999999999999 jüaani, ei arva su arvuti, et saad osta 10 jüaani kaupa. Mõned programmeerimiskeeled pakuvad selle olukorra lahendamiseks spetsiaalseid valuutatüüpe, kuid Java seda ei tee. Nüüd vaatame, kuidas seda parandada.
Ümardamine Meie esimene reaktsioon on teha ümardamine. Matemaatika klassi ringimeetodit ei saa seadistada nii, et see jätaks mõned kümnendkojad, seda saab teha ainult (hoida kahte kohta): avalik topeltvoor (kahekordne väärtus){ return Math.round(value*100)/100.0; }
Kahjuks ülaltoodud kood ei tööta, 4.015 sisestamine sellele meetodile tagastab 4.01 asemel 4.02, nagu eespool nägime 4.015*100=401.4999999999999 Seega, kui tahame täpset ümardamist, ei saa me kasutada lihtsaid tüüpe ühegi operatsiooni tegemiseks java.text.DecimalFormat ei lahenda seda probleemi samuti: System.out.println(new java.text.DecimalFormat("0.00").format(4.025)); Väljund on 4,02
BigDecimal See põhimõte on mainitud ka raamatus "Effective Java", float ja double saab kasutada ainult teaduslikes või inseneriarvutustes ning äriarvutites tuleb kasutada java.math.BigDecimal. On 4 viisi, kuidas BigDecimali ehitada, meid ei huvita kaks, mis on tehtud BigIntegeriga, seega on veel kaks, mis on: BigDecimal (topeltval) Tõlgib topelt BigDecimal'iks. BigDecimal (String val) Tõlgib BigDecimali stringi repre sentatsiooni BigDecimaaliks.
API on lühidalt kirjeldatud ja tavaliselt lihtsam kasutada. Võime seda kasutada ilma mõtlemata, mis saab olema probleem? Kui midagi läks valesti, avastasin, et üksikasjalikus kirjelduses oli selline lõik, mis näitab, milline ülaltoodud meetoditest on piisav: Märkus: selle konstruktori tulemused võivad olla mõnevõrra ettearvamatud. Võiks eeldada, et uus Suurdekümm(.1) on täpselt võrdne 0,1-ga, kuid tegelikult on see võrdne .1000000000000000055511151231257827021181583404541015625-ga. See on nii, sest .1 ei saa täpselt esitada topeltna (või binaarse murruna, mis tahes lõpliku pikkusega). Seega ei ole konstruktorile edastatav pikk väärtus täpselt võrdne 0,1-ga, hoolimata välimusest. (String) konstruktor on seevastu täiesti ennustatav: uus BigDecimal(".1") on täpselt võrdne 0,1-ga, nagu võiks oodata. Seetõttu soovitatakse üldiselt eelistada (string) konstruktorit selle asemel.
Selgub, et kui peame täpselt arvutama, peame kasutama stringi, et luua BigDecimal! Näide raamatus Effective Java kasutab stringi BigDecimali loomiseks, kuid raamat ei rõhuta seda, mis võib olla väike viga.
Lahendus Nüüd, kui see probleem on lahendatud, on põhimõte kasutada BigDecimal'i ja kindlasti kasutada stringi. Aga kujutage ette, et kui tahame teha liitmisoperatsiooni, peame esmalt teisendama kaks ujukomaarvu stringiks, seejärel looma BigDecimal'i, kutsuma ühe puhul liitmismeetodi, edastama teise argumendina ja seejärel teisendama operatsiooni tulemuse (BigDecimal) ujukomaarvuks. Kas suudad sellist tüütut protsessi taluda? Allpool anname tööriistaklassi Arith operatsiooni lihtsustamiseks. See pakub järgmisi staatilisi meetodeid, sealhulgas liitmist, lahutamist, korrutamist ja jagamist ning ümardamist: Public Static Double AD (double v1, double v2) Avalik staatiline topeltsubwoofer (topelt v1, topelt v2) Public Static Double MUL (Double V1, Double V2) Public Static Double Div (Double V1, Double V2) Public Static Double Div (double v1, double v2, int skaala) Avalik staatiline topeltvoor (topelt V, intellekti skaala)
Lisa
Lähtefail Arith.java:
import java.math.BigDecimal; /** * Kuna Java lihtsad tüübid ei suuda täpselt ujukomaarvutusi teha, pakub see tööriistaklass trahve * Täpsed ujukoma-operatsioonid, sealhulgas liitmine, lahutamine, korrutamine, jagamine ja ümardamine. */
public class Arith{
Vaikimisi divisjoni operatsiooni täpsus privaatne staatiline lõplik intellekt DEF_DIV_SCALE = 10;
Seda klassi ei saa instantsierida private Arith(){ }
/** * Pakub täpseid liitmisoperatsioone. * @param v1 lisatakse * @param v2 lisandus * @return Kahe parameetri summa */
Public static double add(double v1,double v2){ BigDecimal b1 = uus BigDecimal (Double.toString(v1)); BigDecimal b2 = uus BigDecimal (Double.toString(v2)); return b1.add(b2).doubleValue(); }
/** * Pakub täpseid lahutamisoperatsioone. * @param v1 lahutatakse * @param v2 miinus * @return Kahe parameetri erinevus */
avalik staatiline double sub(double v1, double v2){ BigDecimal b1 = uus BigDecimal (Double.toString(v1)); BigDecimal b2 = uus BigDecimal (Double.toString(v2)); return b1.subtract(b2).doubleValue(); }
/** * Pakub täpseid korrutamisoperatsioone. * @param v1 korrutatakse * @param v2 kordaja * @return Kahe parameetri korrutis */
Public static double mul(double v1, double v2){ BigDecimal b1 = uus BigDecimal (Double.toString(v1)); BigDecimal b2 = uus BigDecimal (Double.toString(v2)); return b1.multiply(b2).doubleValue(); }
/** * Pakub (suhteliselt) täpseid jagamisoperatsioone, kui toimub ammendamatu jagamine * 10 kümnendkohta ja järgmised numbrid ümardatakse. * @param v1 on jagatud * @param v2 jagaja * @return Kahe parameetri jagatis */
Public static double div(double v1, double v2){ tagasidiv (v1,v2,DEF_DIV_SCALE); }
/** * Pakub (suhteliselt) täpseid diviisioperatsioone. Kui tekib ammendamatu olukord, tähistatakse seda skaala parameetriga * Määra täpsus ja numbrid pärast seda ümardatakse. * @param v1 on jagatud * @param v2 jagaja * @param skaala näitab, et see peab olema täpne mõne kümnendkohani. * @return Kahe parameetri jagatis */
Public Static Double Div(double v1,double v2,int scale){ if(scale<0){ viska uus IllegalArgumentException( "Skaala peab olema positiivne täisarv või null"); } BigDecimal b1 = uus BigDecimal (Double.toString(v1)); BigDecimal b2 = uus BigDecimal (Double.toString(v2)); return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); }
/** * Tagab täpse kümnendkomaa ümardamise. * @param v nõuab numbrite ümardamist * @param skaala on reserveeritud pärast kümnendkomaa * @return Ümardatud tulemused */
avalik staatiline topeltvoor (topelt v, intellekti skaala){ if(scale<0){ viska uus IllegalArgumentException( "Skaala peab olema positiivne täisarv või null"); } BigDecimal b = uus BigDecimal(Double.toString(v)); BigDecimal üks = uus BigDecimal ("1"); return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } }; |
Eelmine:On parem mitte määrata tähendusega stringi põhivõtmeksJärgmine:JDK, JRE, JVM erinevused ja seosed
|