CodeGym/Java Blog/Random/BigDecimal sa Java
John Squirrels
Antas
San Francisco

BigDecimal sa Java

Nai-publish sa grupo
Hi! Sa aralin ngayon, pag-uusapan natin ang malaking bilang. Hindi, I mean TALAGANG MALAKI. Paulit -ulit naming nakatagpo ang talahanayan ng mga hanay ng halaga para sa mga primitive na uri ng data. Mukhang ganito:
Primitive na uri Sukat sa memorya Saklaw ng halaga
byte 8 bit -128 hanggang 127
maikli 16 bit -32768 hanggang 32767
char 16 bit 0 hanggang 65536
int 32 bits -2147483648 hanggang 2147483647
mahaba 64 bit -9223372036854775808 hanggang 9223372036854775807
lumutang 32 bits (2 sa kapangyarihan ng -149) sa ((2 sa kapangyarihan ng -23) * 2 sa kapangyarihan ng 127)
doble 64 bit (-2 sa kapangyarihan ng 63) hanggang ((2 sa kapangyarihan ng 63) - 1)
boolean 8 (kapag ginamit sa array), 32 (kapag hindi ginamit sa array) Tama o mali
Ang pinakamalawak na uri ng data ng integer ay ang long . Pagdating sa mga floating-point na numero, ito ay ang double . Ngunit paano kung ang bilang na kailangan natin ay napakalaki na hindi man lang ito kasya sa isang mahaba ? Ang Long data type ay may medyo malaking hanay ng mga posibleng value, ngunit limitado pa rin ito sa 64 bits. Ano ang kailangan nating makabuo kung ang ating Napakalaking Numero ay nangangailangan ng 100 bits? Sa kabutihang palad, hindi namin kailangang mag-imbento ng anuman. Para sa mga kaso tulad nito, ang Java ay may dalawang espesyal na klase: BigInteger (para sa mga integer) at BigDecimal(para sa mga floating-point na numero). Ano ang ginagawa nilang espesyal? Una sa lahat, sa teorya, wala silang maximum na laki. Sinasabi namin na "sa teorya", dahil walang mga computer na may walang katapusang memorya. At kung ang iyong programa ay lumilikha ng isang numero na mas malaki kaysa sa halaga ng magagamit na memorya, kung gayon, ang programa ay hindi gagana, siyempre. Ngunit ang mga ganitong kaso ay hindi malamang. Bilang resulta, masasabi nating ang BigInteger at BigDecimal ay maaaring kumatawan sa mga numero ng halos walang limitasyong laki. Ano ang ginagamit ng mga klase na ito? Una sa lahat, para sa mga kalkulasyon na may lubhang mahigpit na mga kinakailangan sa katumpakan. Halimbawa, ang buhay ng tao ay maaaring depende sa katumpakan ng mga kalkulasyon sa ilang mga programa (hal. software na kumokontrol sa mga eroplano, rocket, o kagamitang medikal). Kaya kung mahalaga ang ika-150 decimal place, BigDecimalay ang pinakamahusay na pagpipilian. Bilang karagdagan, ang mga bagay ng klase na ito ay madalas na ginagamit sa mundo ng pananalapi, kung saan ang tumpak na pagkalkula ng kahit na ang pinakamaliit na halaga ay napakahalaga din. Paano ka gumagana sa BigInteger at BigDecimal na mga bagay at kailangan mo bang malaman ang 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 sa constructor ay isa lamang posibleng opsyon. Dito gumagamit kami ng mga string, dahil ang aming mga numero ay lumampas sa maximum na mga halaga para sa long at double , at kailangan namin ng ilang paraan upang ipaliwanag sa compiler kung aling numero ang gusto naming gawin :) Ipasa lang ang numerong 11111111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 sa constructor ay hindi gagana: Susubukan ng Java na i-cram ang naipasa na numero sa isa sa mga primitive na uri ng data, ngunit hindi ito magkasya sa alinman sa mga ito. Kaya naman ang paggamit ng string upang maipasa ang nais na numero ay isang magandang opsyon. Ang parehong mga klase ay maaaring awtomatikong mag-extract ng mga numerical na halaga mula sa mga naipasa na mga string. Ang isa pang mahalagang punto na dapat tandaan kapag nagtatrabaho sa malalaking numero na mga klase ay ang kanilang mga bagay ay hindi nababago ( Immutable ). Pamilyar ka na sa immutability salamat sa iyong karanasan sa String class at mga wrapper class para sa mga primitive na uri (Integer, Long, atbp.).
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:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Tulad ng iyong inaasahan, ang aming numero ay hindi nagbabago. Upang maisagawa ang pagpapatakbo ng karagdagan, dapat kang lumikha ng isang bagong bagay upang matanggap ang resulta ng operasyon.
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:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Kita n'yo, ngayon gumagana na ang lahat ng nararapat :) Sa pamamagitan ng paraan, napansin mo ba kung gaano kakaiba ang hitsura ng operasyon ng karagdagan?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Ito ay isa pang mahalagang punto. Ang mga malalaking numerong klase ay hindi gumagamit ng + - * / operator. Sa halip, nagbibigay sila ng isang hanay ng mga pamamaraan. Kilalanin natin ang mga pangunahing (tulad ng nakasanayan, makakahanap ka ng kumpletong listahan ng mga pamamaraan sa dokumentasyon ng Oracle: dito at dito ).
  1. pamamaraan para sa mga pagpapatakbo ng aritmetika: add() , subtract() , multiply() , divide() . Ang mga pamamaraang ito ay ginagamit upang maisagawa ang pagdaragdag, pagbabawas, pagpaparami at paghahati, ayon sa pagkakabanggit.

  2. doubleValue() , intValue() , floatValue() , longValue() , atbp. ay ginagamit upang i-convert ang isang malaking numero sa isa sa mga primitive na uri ng Java. Mag-ingat kapag ginagamit ang mga pamamaraang ito. Huwag kalimutan ang tungkol sa mga pagkakaiba sa laki ng bit!

    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. Hinahayaan ka ng min() at max() na mahanap ang minimum at maximum na halaga ng dalawang malalaking numero.
    Tandaan na ang mga pamamaraang ito 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 gawi

Ang paksang ito ay may sariling hiwalay na seksyon, dahil ang pag-round ng malalaking numero at pag-configure ng pag-ikot ng gawi ay hindi gaanong simple. Maaari mong gamitin ang setScale() na paraan upang itakda ang bilang ng mga decimal na lugar para sa isang BigDecimal . Halimbawa, ipagpalagay na gusto namin ang numerong 111.5555555555 na magkaroon ng tatlong digit pagkatapos ng decimal point. Gayunpaman, hindi namin makakamit ang gusto namin sa pamamagitan ng pagpasa sa numero 3 bilang argumento sa setScale() na pamamaraan. Tulad ng nabanggit sa itaas, BigDecimalay para sa kumakatawan sa mga numero na may mahigpit na mga kinakailangan sa computational precision. Sa kasalukuyang anyo nito, ang aming numero ay may 10 digit pagkatapos ng decimal point. Nais naming i-drop ang 7 sa kanila at panatilihin lamang ang 3. Alinsunod dito, bilang karagdagan sa numero 3, dapat naming ipasa ang rounding mode. Ang BigDecimal ay may kabuuang 8 rounding mode. marami yan! Ngunit kung kailangan mo talagang ayusin ang katumpakan ng iyong mga kalkulasyon, makukuha mo ang lahat ng kailangan mo. Kaya, narito ang 8 rounding mode na inaalok ng BigDecimal :
  1. ROUND_CEILING — round up

    111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
  2. ROUND_DOWN — mga round patungo sa zero

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

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

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

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

    0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5
    0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
  6. ROUND_HALF_EVEN — nakadepende ang pag-round sa numero sa kaliwa ng decimal point. Kung ang numero sa kaliwa ay pantay, ang pag-round ay magiging pababa. Kung ang numero sa kaliwa ng decimal point ay kakaiba, ang pag-round ay magiging pataas.

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

    Ang numero sa kaliwa ng decimal na lugar ay 2 (even). Ang numero ay bilugan pababa. Gusto namin ng 0 decimal na lugar, kaya ang resulta ay 2.

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

    Ang numero sa kaliwa ng decimal point ay 3 (odd). Ang numero ay bilugan. Gusto namin ng 0 decimal na lugar, kaya ang resulta ay 4.

  7. ROUND_UNNECCESSARY — Ginagamit ang mode na ito kapag kailangan mong ipasa ang isang rounding mode sa isang paraan, ngunit hindi kailangang bilugan ang numero. Kung susubukan mong i-round ang isang numero gamit ang ROUND_UNNECCESSARY mode set, isang ArithmeticException ang ihahagis.

    3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
  8. ROUND_UP — mga round palayo sa zero.

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

Paghahambing ng malalaking numero

Mahalaga rin ito. Maaalala mo na ginagamit namin ang equals() na pamamaraan ay ihambing ang mga bagay sa Java. Ang pagpapatupad ay ibinibigay ng wika mismo (para sa mga karaniwang klase ng Java) o na-override ng programmer. Ngunit sa kaso ng mga BigDecimal na bagay, ang paggamit ng equals() na paraan para sa mga paghahambing ay hindi inirerekomenda. Ito ay dahil ang BigDecimal.equals() na pamamaraan ay nagbabalik ng true lamang kung ang 2 numero ay may parehong halaga at sukat: Paghambingin natin ang pag-uugali ng equals() na pamamaraan para sa Double at BigDecimal na mga klase:
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, para sa BigDecimal , ang mga numerong 1.5 at 1.50 ay naging hindi pantay! Ito ay dahil mismo sa mga detalye ng pagpapatupad ng equals() na pamamaraan sa klase ng BigDecimal . Para sa mas tumpak na paghahambing ng dalawang BigDecimal na bagay, mas mainam na gamitin ang compareTo() na paraan:
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 compareTo() method ay nagbalik ng 0, na nangangahulugan na ang 1.5 at 1.50 ay pantay. At ito ang resulta na inaasahan namin! :) Iyan ang nagtatapos sa ating aralin ngayon. Ngayon ay oras na upang bumalik sa mga gawain! :)
Mga komento
  • Sikat
  • Bago
  • Luma
Dapat kang naka-sign in upang mag-iwan ng komento
Wala pang komento ang page na ito