JavaRush /Java Blog /Random-TL /BigDecimal sa Java

BigDecimal sa Java

Nai-publish sa grupo
Kamusta! Sa lecture ngayon ay pag-uusapan natin ang tungkol sa malalaking numero. Hindi, tungkol sa mga TALAGANG MALAKI. Dati , nakakita kami ng talahanayan ng mga hanay ng halaga para sa mga primitive na uri ng data nang higit sa isang beses. Mukhang ganito:
Primitive na uri Sukat sa memorya Saklaw ng mga halaga
byte 8 bit -128 hanggang 127
maikli 16 bit hanggang -32768 hanggang 32767
char 16 bit mula 0 hanggang 65536
int 32 bits mula -2147483648 hanggang 2147483647
mahaba 64 bits mula -9223372036854775808 hanggang 9223372036854775807
lumutang 32 bits mula sa (2 hanggang sa kapangyarihan -149) hanggang sa ((2-2 hanggang sa kapangyarihan -23)*2 hanggang sa kapangyarihan 127)
doble 64 bits mula sa (-2 hanggang sa kapangyarihan ng 63) hanggang sa ((2 hanggang sa kapangyarihan ng 63) - 1)
boolean 8 (kapag ginamit sa mga array), 32 (kapag ginamit sa mga hindi array) Tama o mali
Kung pinag-uusapan natin ang tungkol sa mga integer, ang pinakamalawak na uri ng data ay mahaba , at kapag pinag-uusapan natin ang mga numero ng floating point, double . Ngunit paano kung ang bilang na kailangan natin ay napakalaki na hindi man lang ito magkasya sa mahaba ? Ang hanay ng mga posibleng Mahabang halaga ay medyo malaki, ngunit limitado pa rin sa isang tiyak na laki - 64 bits. Ano ang maaari nating maisip kung ang ating Napakalaking Numero ay tumitimbang ng 100 bits? Sa kabutihang palad, hindi mo kailangang mag-imbento ng anuman. Sa Java, dalawang espesyal na klase ang ginawa para sa mga ganitong kaso - BigInteger (para sa mga integer) at BigDecimal (para sa mga floating-point na numero). Ano ang kanilang tampok? Una sa lahat, sila ay theoretically ay walang maximum na laki. Theoretically, dahil walang mga computer na may walang katapusang memorya. At kung lumikha ka ng isang numero sa programa na mas malaki kaysa sa laki ng memorya ng computer, siyempre, ang programa ay hindi gagana. Ngunit ang mga ganitong kaso ay hindi malamang. Samakatuwid, maaari nating sabihin na ang laki ng mga numero BigIntegeray BigDecimalhalos walang limitasyon. Ano ang ginagamit ng mga klase na ito? Una sa lahat, para sa mga kalkulasyon na may napakataas na mga kinakailangan sa katumpakan. Mayroong, halimbawa, mga programa kung saan ang buhay ng tao ay maaaring depende sa katumpakan ng mga kalkulasyon (software para sa mga eroplano at rocket o para sa mga medikal na kagamitan). Samakatuwid, kung kahit na ang ika-150 decimal place ay gumaganap ng isang mahalagang papel, BigDecimalito ang pinakamahusay na pagpipilian. Bilang karagdagan, kadalasan ang mga bagay na ito ay ginagamit sa mundo ng pananalapi, kung saan ang katumpakan ng mga kalkulasyon hanggang sa pinakamaliit na halaga ay napakahalaga din. Paano magtrabaho sa mga bagay BigIntegerat BigDecimalano ang mahalagang tandaan tungkol sa mga ito? Ang mga bagay ng mga klase na ito ay nilikha tulad nito:
public class Main {

   public static void main(String[] args) {

       BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
       System.out.println(integer);

       BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
       System.out.println(decimal);
   }
}
Ang pagpasa ng string bilang parameter ay isa lamang sa mga posibleng constructor. Here we use strings because our numbers exceed the maximum values long​​and double, and somehow we need to explain to the compiler exactly what number we want to get :) Just pass the number 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 to the constructor 1111111111111111111111111111111111111111111111111111111111111111111 will not work: Java will try to "magkasya" sa naipasa na numero sa isa sa mga primitive na uri ng data, ngunit hindi ito magkasya sa alinman sa mga ito. Samakatuwid, ang paggamit ng isang string upang maipasa ang nais na numero ay isang magandang opsyon. Ang parehong mga klase ay maaaring awtomatikong mag-extract ng mga numerong halaga mula sa mga naipasa na mga string. Ang isa pang mahalagang punto na dapat tandaan kapag nagtatrabaho sa malalaking bilang ng mga klase ay ang kanilang mga bagay ay hindi nababago ( Immutable) . Kilalang-kilala mo na ang prinsipyo ng immutability sa pamamagitan ng halimbawa ng class Stringat wrapper classes para sa primitives (Integer, Long at iba pa).
import java.math.BigInteger;

public class Main {

   public static void main(String[] args) {

       BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
       System.out.println(integer);

       integer.add(BigInteger.valueOf(33333333));
       System.out.println(integer);

   }
}
Output ng console:

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Ang aming mga numero ay hindi nagbago, gaya ng iyong inaasahan. Para magtagumpay ang pagpapatakbo ng karagdagan, dapat kang lumikha ng bagong bagay at italaga ang resulta ng pagdaragdag dito.
import java.math.BigInteger;

public class Main {

   public static void main(String[] args) {

       BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
       System.out.println(integer);

       BigInteger result = integer.add(BigInteger.valueOf(33333333));
       System.out.println(result);

   }
}
Output ng console:

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Ngayon ang lahat ay gumagana ayon sa nararapat :) Sa pamamagitan ng paraan, napansin mo ba kung gaano kakaiba ang hitsura ng pagdaragdag?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Ito ay isa pang mahalagang punto. Ang malalaking bilang ng mga klase ay hindi gumagamit ng +-*/ na mga operator sa kanilang operasyon, ngunit sa halip ay nagbibigay ng isang hanay ng mga pamamaraan. Tingnan natin ang mga pangunahing (maaari kang, gaya ng dati, maghanap ng kumpletong listahan ng mga pamamaraan sa dokumentasyon ng Oracle: dito at dito ).
  1. mga pamamaraan para sa pagsasagawa ng mga operasyong aritmetika: add() , subtract(), multiply(), divide(). Ginagamit para sa pagdaragdag, pagbabawas, pagpaparami at paghahati ayon sa pagkakabanggit.

  2. doubleValue(), intValue(), floatValue(), longValue()atbp. - Ginagamit upang i-convert ang isang malaking numero sa isang primitive na uri ng Java. Mag-ingat kapag ginagamit ang mga ito at tandaan ang pagkakaiba sa kapasidad!

    import java.math.BigInteger;
    
    public class Main {
    
       public static void main(String[] args) {
    
           BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
    
           long result = integer.longValue();
           System.out.println(result);
    
       }
    }

    Output ng console:

    
    8198552921648689607
  3. min()at max()- nagbibigay-daan sa iyo upang mahanap ang minimum at maximum na halaga ng dalawang malalaking numero na naipasa.
    Mangyaring tandaan: ang mga pamamaraan ay hindi static!

    import java.math.BigInteger;
    
    public class Main {
    
       public static void main(String[] args) {
    
           BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
           BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222");
    
           System.out.println(integer.max(integer2));
    
       }
    }

    Output ng console:

    
    222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222

BigDecimal rounding control

Ang paksang ito ay kasama sa isang hiwalay na seksyon, dahil ang pag-ikot ng malalaking numero at pagsasaayos nito ay hindi isang simpleng bagay. Maaari mong itakda ang bilang ng mga decimal na lugar para sa isang numero BigDecimalgamit ang setScale(). Halimbawa, gusto naming itakda ang katumpakan ng numerong 111.5555555555 sa tatlong decimal na lugar. Gayunpaman, hindi namin maipapasa ang numero 3 bilang argumento sa pamamaraan setScale()at sa gayon ay malulutas ang aming problema. Tulad ng nabanggit sa itaas, BigDecimalito ay mga numero para sa mga kalkulasyon na may mas mataas na katumpakan. Sa kasalukuyang anyo nito, ang aming numero ay may 10 decimal na lugar. Gusto naming itapon ang 7 sa kanila at mag-iwan lamang ng 3. Samakatuwid, bilang karagdagan sa numero 3, dapat naming ipasa ang rounding mode bilang isang parameter . Mayroong 8 rounding mode sa kabuuan BigDecimal. medyo marami! Ngunit kung kailangan mong talagang ayusin ang katumpakan ng mga kalkulasyon sa programa, magkakaroon ka ng lahat ng kailangan mo para dito. Kaya, narito ang 8 rounding mode na magagamit sa BigDecimal:
  1. ROUND_CEILING- pag-ikot

    111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
  2. ROUND_DOWN- pagtatapon ng discharge

    111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
  3. ROUND_FLOOR- pagbilog pababa

    111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555

  4. ROUND_HALF_UP— pag-round up kung ang numero pagkatapos ng decimal point >= .5

    0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6
    0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
  5. ROUND_HALF_DOWN— pag-round up kung ang numero pagkatapos ng decimal point > .5

    0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5
    0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
  6. ROUND_HALF_EVEN— Ang pag-round ay depende sa numero sa kaliwa ng decimal point. Kung ang numero sa kaliwa ay pantay, ang pag-round ay gagawin pababa. Kung ang numero sa kaliwa ng decimal point ay kakaiba, ito ay i-round up.

    2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2

    Ang numero sa kaliwa ng decimal point - 2 - ay pantay. Ang pag-ikot ay nangyayari pababa. Dahil kailangan namin ng 0 decimal na lugar, ang magiging resulta ay 2.

    3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4

    Ang numero sa kaliwa ng decimal point - 3 - ay kakaiba. Ang pag-ikot ay nangyayari paitaas. Dahil kailangan namin ng 0 decimal na lugar, ang magiging resulta ay 4.

  7. ROUND_UNNECCESSARY— ginagamit sa mga kaso kung saan ang rounding mode ay kailangang ipasa sa ilang paraan, ngunit ang numero ay hindi kailangang bilugan. Kung susubukan mong i-round ang isang numero kapag ang ROUND_UNNECCESSARY mode ay nakatakda, isang ArithmeticException ang ihahagis.

    3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
  8. ROUND_UP- pag-ikot.

    111.5551 -> setScale(3, ROUND_UP) -> 111.556

Paghahambing ng malalaking numero

Mahalaga rin ang tanong na ito. Naaalala mo na na ang pamamaraan ay ginagamit upang ihambing ang mga bagay sa Java equals(). Ito ay ibinibigay ng wika mismo (sa kaso ng mga built-in na klase ng Java) o na-override ng programmer. Ngunit sa kaso ng mga bagay sa klase, hindi inirerekomenda BigDecimalna gamitin ang pamamaraan equals()para sa paghahambing. Ang dahilan nito ay ang BigDecimal.equals()dalawang-numero na pamamaraan ay nagbabalik lamang ng totoo kung ang dalawang numero ay may parehong halaga at sukatequals() : Ihambing natin ang pag-uugali ng y Doubleat y na pamamaraan BigDecimal:
import java.math.BigDecimal;

public class Main {

   public static void main(String[] args) {

       Double a = 1.5;
       Double b = 1.50;

       System.out.println(a.equals(b));

       BigDecimal x = new BigDecimal("1.5");
       BigDecimal y = new BigDecimal("1.50");

       System.out.println(x.equals(y));

   }
}
Output ng console:

true
false
Tulad ng nakikita mo, ang mga numero 1.5 at 1.50 sa kaso ng c BigDecimalay naging hindi pantay! Nangyari ito nang eksakto dahil sa mga detalye ng pamamaraan equals()sa klase BigDecimal. Para sa isang mas tamang paghahambing ng dalawa, BigDecimalmas mainam na gamitin ang pamamaraan compareTo():
import java.math.BigDecimal;

public class Main {

   public static void main(String[] args) {

       BigDecimal x = new BigDecimal("1.5");
       BigDecimal y = new BigDecimal("1.50");

       System.out.println(x.compareTo(y));

   }
}
Output ng console:

0
Ang pamamaraan compareTo()ay nagbalik ng 0, na nangangahulugang katumbas ng 1.5 at 1.50. Ito ang resulta na aming inaasahan! :) Dito nagtatapos ang ating aralin para sa araw na ito. Oras na para bumalik sa mga gawain! :)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION