JavaRush /Java Blog /Random-TL /BigInteger at BigDecimal

BigInteger at BigDecimal

Nai-publish sa grupo
Sa Java, ang isang application ay binubuo ng mga klase, at ang mga klase ay binubuo ng mga pamamaraan at variable. Ang mga variable, sa turn, ay nahahati sa primitive at reference. BigInteger at BigDecimal - 1Mayroong 8 uri ng mga variable sa Java at, hindi kasama ang booleanat char, nahahati sila sa mga sumusunod na uri:
  • mga integer: byte, short, intat long;
  • lumulutang na punto (tinatawag ding tunay na mga numero): floatat double.
Sa loob ng maliliit na grupong ito, ang mga pagkakaiba ay umiiral lamang sa hanay ng mga halaga na maaaring nilalaman (at, nang naaayon, ang sinasakop na espasyo ng naturang variable ay nag-iiba). Ang pinakamalaki sa mga uri ng integer ay long, na may saklaw mula -9223372036854775808 hanggang 9223372036854775807. Sa mga numero ng floating point, double, na may saklaw na 1.7e-308 hanggang 1.7e+308. Maaari kang magbasa nang higit pa tungkol sa mga tunay na numero sa artikulong ito . Ngunit paano kung kailangan nating mag-imbak ng mga numero na lumampas sa katanggap-tanggap na hanay? Sa kasong ito, kakailanganin natin BigIntegerat BigDecimal.

BigInteger sa Java

Ang Java class BigIntegeray ginagamit bilang isang analogue sa arbitrary-length integer values ​​na walang 64-bit na limitasyon ng haba. Bukod dito, ito ay isang inapo ng class Number, tulad ng mga karaniwang wrapper para sa mga simpleng uri ng numero - Integer, Long, Byte, Doubleat iba pa - samakatuwid mayroon itong mga pagpapatupad ng mga pamamaraan na humahantong sa mga simpleng uri:
BigInteger value = new BigInteger("32145");

int intValue = value.intValue();//32145

long longValue = value.longValue();//32145

double doubleValue = value.doubleValue();//32145.0
Kaagad naming nakita ang paglikha ng naturang bagay BigIntegerna ang aming halaga ay ipinasa sa tagabuo, ngunit sa format na string. Kapansin-pansin na mayroon siyang higit sa isang taga-disenyo, ngunit para sa lahat ng okasyon. Kung ang mga primitive na uri ay hindi tumanggap ng buong dami ng data mula sa BigInteger, ang data ay puputulin sa hanay ng primitive na uri na iyon. Ngunit sa parehong oras, may mga analogue ng mga pamamaraan na ito ( intValueExact(), longValueExact()atbp.), na ang pagkakaiba lamang ay kung ang simpleng uri kung saan ang conversion ay nagaganap ay hindi tumanggap ng hanay ng data, isang ArithmeticException ay itinapon .

BigInteger constants

Para sa panloob na paggamit, ang klase ay may mga pare-pareho:
BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
Ito ay mga pare-parehong bagay BigIntegerna may mga halaga, ayon sa pagkakabanggit, 0, 1at 10.

Mga Paraan ng BigInteger

Isa sa mga pangunahing tampok ng klase na ito ay puno ito ng mga pamamaraan na nagpapatupad ng mga karaniwang operasyon ng aritmetika sa Java. Halimbawa:
  • mga operasyon ng pagbubuod:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.add(secondValue);//73461
  • pagpaparami ng operasyon:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.multiply(secondValue);//1347530670
  • mga operasyon ng paghahanap ng natitira kapag hinahati ang isang numero sa isa pa:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.remainder(secondValue);//2529
  • pagkuha ng ganap na halaga ng isang numero (iyon ay, modulo, unsigned):

    BigInteger firstValue = new BigInteger("-37995");
    BigInteger resultValue =  firstValue.abs();//37995
Mayroon ding mga pamamaraan para sa mas kumplikadong (tiyak) na mga operasyon:
  • mga operasyon na may pagkalkula ng mod :

    BigInteger firstValue = new BigInteger("-34");
    BigInteger secondValue = new BigInteger("5");
    BigInteger resultValue = firstValue.mod(secondValue); //1
Mayroong ilang iba't ibang mga pagkakaiba-iba ng function na ito:
  • pagkuha ng random na numero at pagtukoy ng bilang ng mga bit na gagamitin ng resultang halaga:

    BigInteger firstValue = BigInteger.probablePrime(8, new Random());//211
    BigInteger secondValue = BigInteger.probablePrime(16, new Random());//42571
  • bitwise shift operations(ito >> n)

    Lumipat pakaliwa:

    BigInteger firstValue = new BigInteger("5");
    BigInteger firstResultValue = firstValue.shiftLeft(3);//40

    Lumipat pakanan:

    BigInteger secondValue = new BigInteger("34");
    BigInteger secondResultValue = secondValue.shiftRight(2); //8
Siyempre, mas mahusay na tingnan ang buong listahan ng mga pamamaraan sa dokumentasyon . BigInteger at BigDecimal - 2

BigDecimal sa Java

Kapag kailangan natin ng totoong bilang ng di-makatwirang haba, ginagamit ang klase ng Java - BigDecimal. Bilang panuntunan, ginagamit ito upang magtrabaho sa pananalapi sa halip na double, dahil nagbibigay ito ng higit pang mga pagpipilian sa pag-customize. Tulad ng at BigInteger, BigDecimalay isang inapo ng isang klase Numberat may mga pamamaraan na nagbabalik ng halaga ng isang bagay bilang isang partikular na primitive na uri:
BigDecimal value = new BigDecimal(35563.3);

long longValue = value.longValue();//35563

double doubleValue = value.doubleValue();//35563.3
Tulad ng nakikita natin kapag binabawasan sa long, ang bahagi na lang ng integer ang nananatili, at ang mga decimal na lugar ay itinatapon.

BigDecimal constructor

Susuriin natin ang mga constructor BigDecimal, dahil ang klase ay may mas malawak na seleksyon ng mga ito. May mga constructor na nagbibigay-daan sa iyo upang itakda ang halaga ng isang bagay sa iba't ibang paraan (sa pamamagitan ng pagpasa int, long, double, Stringat even BigInteger), at may mga nagpapahintulot nito. itakda ang mga setting ng nilikha na bagay (mga pamamaraan ng pag-round, bilang ng mga decimal na lugar):
BigDecimal firstValue = new BigDecimal("455656.545");//455656.545
Malinaw ang lahat dito, direkta naming itinatakda ang halaga at bilang ng mga decimal na lugar na gusto naming makita.
BigDecimal secondValue = new BigDecimal(3445.54);//3445.5399999999999636202119290828704833984375
Ang mga resulta ng constructor na ito ay maaaring medyo hindi mahuhulaan, dahil tinutukoy namin ang isang double, na sa pamamagitan ng likas na katangian nito ay isang napaka-hindi maliwanag na uri. Samakatuwid, ito ay karaniwang inirerekomenda na gamitin sa isang constructor String.
BigDecimal thirdValue = new BigDecimal(3445.554645675444, MathContext.DECIMAL32);//3445.555
Itinakda namin ang double, ngunit kasabay nito, nagtatakda din kami ng parameter na naglalarawan sa panuntunan sa pag-ikot (na naglalaman ng bilang ng mga decimal na lugar at algorithm para sa pag-round).
char[] arr = new String("455656.545").toCharArray();

BigDecimal fourthValue = new BigDecimal(arr, 2, 6);//5656.5
Nagtakda kami ng isang hanay ng mga character mula sa kung aling elemento kinukuha namin ang mga halaga para sa bagay at kung ilan sa mga elementong ito ang kinukuha namin.
BigDecimal fifthValue = new BigDecimal(new BigInteger("44554"), 3);//44.554
Kumuha kami ng isang umiiral nang object BigInteger, itakda ang bilang ng mga decimal na lugar.

Mga Paraan ng BigDecimal

Naglalaman din ang klase BigDecimalng mga pamamaraan para sa iba't ibang mga pagpapatakbo ng aritmetika, ngunit BigIntegerwala itong mga pamamaraan para sa pagtatrabaho sa mga bit, tulad ng . Ngunit gayunpaman, ang pangunahing tampok BigDecimalay ang kakayahang umangkop sa pagtatrabaho sa mga numero ng lumulutang na punto. Tingnan natin ang ilang mga pamamaraan na nagbibigay sa atin ng kapangyarihang makabisado ang mga tunay na numero:
  • nakukuha namin ang katumpakan (bilang ng mga numero):

    BigDecimal value = new BigDecimal("454334.34334");
    int result = value.precision();//11
  • itakda ang bilang ng mga decimal place at ang rounding rule:

    BigDecimal firstValue = new BigDecimal(3445.544445);
    
    BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_CEILING);//3445.545

    Sa ibaba ay titingnan natin ang mga constant para sa pagtatakda ng mga panuntunan sa pag-ikot.

  • hatiin BigDecimalsa isa pa BigDecimal, habang isinasaad ang kinakailangang bilang ng mga decimal na lugar at ang panuntunan sa pag-round:

    BigDecimal firstValue = new BigDecimal("455656.545");
    
    BigDecimal secondValue = new BigDecimal(3445.544445);
    
    BigDecimal result = firstValue.divide(secondValue, 2,RoundingMode.DOWN);//132.24
  • paglipat ng decimal point pakanan/kaliwa ng isang tiyak na bilang ng mga lugar:

    BigDecimal value = new BigDecimal("455656.545");
    BigDecimal firstResult = value.movePointRight (2);//45565654.5
    BigDecimal secondResult = value.movePointLeft (2);//4556.56545
  • trim trailing zeros:

    BigDecimal value = new BigDecimal("45056.5000");
    BigDecimal result = value.stripTrailingZeros();//45056.5

    Kung mayroon kaming lahat ng mga zero sa totoong bahagi at mayroon ding mga zero sa buong bahagi (o wala kaming mga decimal na lugar), kung gayon:

    BigDecimal value = new BigDecimal("450000.000");
    BigDecimal result = value.stripTrailingZeros();//4.5E+5

BigDecimal rounding rules

Upang magtakda ng mga panuntunan sa pag-ikot, sa loob BigDecimalay makikita natin ang mga espesyal na constant na naglalarawan ng mga algorithm ng pag-ikot: ROUND_UP- pag-ikot mula sa zero, pag-ikot patungo sa tunay na bahagi:
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_UP );//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UP );//-2.5
ROUND_DOWN— pag-ikot sa zero, iyon ay, pagputol ng tunay na bahagi:
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_DOWN  );//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_DOWN  );//-2.6
ROUND_CEILING— pag-ikot sa positibong infinity. Iyon ay, kung ang aming numero ay positibo, kung gayon -> ROUND_UP, kung negatibo, kung gayon ->ROUND_DOWN
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_CEILING);//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_CEILING);//-2.5
ROUND_FLOOR- rounding to negative infinity, ibig sabihin, kung positive ang number natin, then -> ROUND_DOWN, if negative, then ->ROUND_UP
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_FLOOR);//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_FLOOR);//-2.6
Para sa value na isinasaalang-alang, isasaalang-alang namin ang pinakamalapit na numerong ito na may pinutol na decimal place bilang pinakamalapit na kapitbahay ng numerong isinasaalang-alang. Halimbawa, ang 2.43 ay magiging mas malapit sa 2.4 kaysa sa 2.5, ngunit ang 2.48 ay magiging mas malapit sa 2.5. ROUND_HALF_DOWN— pag-ikot sa "pinakamalapit na kapitbahay". Kung ang parehong kapitbahay ay pantay na layo mula sa isang partikular na halaga, pagkatapos ay ikot hanggang zero ang isasagawa. Ang equidistant ay, halimbawa, kapag ang bilang na binibilog ay 5, at ito ay parehong distansya mula sa 0 at 10):
BigDecimal firstValue = new BigDecimal("2.58");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.6
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.5
ROUND_HALF_UP— mode para sa pag-ikot patungo sa "pinakamalapit na kapitbahay". Kung ang magkapitbahay ay pantay ang layo, ang pag-round up ay tapos na (ito ang parehong rounding na itinuro sa amin sa paaralan):
BigDecimal firstValue = new BigDecimal("2.53");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_HALF_UP  );//2.5
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_UP  );//2.6
ROUND_HALF_EVEN— pag-ikot sa "pinakamalapit na kapitbahay" kung ang parehong kapitbahay ay hindi katumbas ng distansya. Sa kasong ito, kung ang numerong ni-round ay nauunahan ng isang kakaibang numero, ito ay ni-round up, at kung ito ay kahit na, ito ay ni-round down:
BigDecimal firstValue = new BigDecimal("2222.2225");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.222
Nakukuha namin ang resultang ito dahil kapag ang pag-round, ang 5 ay tumitingin sa dating numero 2, at nakikita na ito ay pantay-pantay, bumababa. Ngunit kung:
BigDecimal firstValue = new BigDecimal("2222.22255");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.223
Tumataas ang rounding na iyon, dahil ang huling 5 ay tumitingin sa nakaraang halaga at nakakakita ng kakaibang numero. Bilang resulta, ang numero ay ni-round up sa 6, pagkatapos ay ang susunod na 6 ay din bilugan. Ngunit ang anim ay hindi na tumitingin sa numero sa kaliwa, dahil ang numero ay malinaw na mas malapit pataas, at bilang isang resulta ang huling 2 ay nadagdagan ng 1. ROUND_UNNECESSARY- ginagamit upang suriin na ang numero ay hindi kailangang bilugan. Iyon ay, sinusuri namin na ang numero ay may kinakailangang bilang ng mga decimal na lugar:
BigDecimal firstValue = new BigDecimal("2.55");
BigDecimal firstResult =  firstValue.setScale(2, BigDecimal.ROUND_UNNECESSARY);//2.55
Ang lahat ay maayos dito, ang halaga ay may dalawang digit at sinusuri namin na mayroon lamang dalawang digit pagkatapos ng decimal point. Ngunit kung:
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UNNECESSARY);
Pagkatapos ay makuha namin - ArithmeticException, dahil ang halaga na sinusuri ay lumampas sa tinukoy na bilang ng mga decimal na lugar. Ngunit kung susuriin natin ang dalawang decimal na lugar, ngunit sa katunayan mayroong isa doon, kung gayon ang pagbubukod ay hindi itatapon, at ang mga nawawalang numero ay pupunan lamang ng mga zero:
BigDecimal thirdValue = new BigDecimal("2.5");
BigDecimal thirdResult = thirdValue.setScale(3, BigDecimal.ROUND_UNNECESSARY   );//2.500
Gusto ko ring tandaan na ang y BigDecimalay may mga constant na katulad ng mga constants BigInteger ZERO, ONEat TEN. Narito ang isang link sa dokumentasyon . At sa wakas: tulad ng malamang na napansin mo, kapag nagsasagawa ng mga operasyon sa mga bagay BigIntegerat BigDecimal, hindi namin binabago ang mga luma, ngunit palaging nakakakuha ng mga bago. Sinasabi nito sa atin na sila ay immutable, ibig sabihin, hindi nababago pagkatapos nilang likhain, tulad ng String. Sa madaling salita, ang lahat ng kanilang mga pamamaraan ay hindi maaaring baguhin ang panloob na estado ng bagay; sa karamihan, maaari silang magbalik ng isang bagong bagay na may mga parameter na tinukoy ng function na ginagamit namin.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION