JavaRush /Java blogi /Random-UZ /BigInteger va BigDecimal

BigInteger va BigDecimal

Guruhda nashr etilgan
Java tilida dastur sinflardan, sinflar esa metodlar va o'zgaruvchilardan iborat. O'zgaruvchilar, o'z navbatida, primitiv va mos yozuvlarga bo'linadi. BigInteger va BigDecimal - 1Java-da 8 turdagi o'zgaruvchilar mavjud va booleanva dan tashqari charular quyidagi turlarga bo'linadi:
  • butun sonlar: byte, short, intva long;
  • suzuvchi nuqta (haqiqiy sonlar deb ham ataladi): floatva double.
Ushbu kichik guruhlar ichida farqlar faqat o'z ichiga olishi mumkin bo'lgan qiymatlar oralig'ida mavjud (va shunga mos ravishda bunday o'zgaruvchining egallagan maydoni o'zgaradi). Butun son turlarining eng kattasi long-9223372036854775808 dan 9223372036854775807 oralig'ida. O'zgaruvchan nuqtali raqamlardan , double1,7e-308 dan 1,7e+308 oralig'ida. Haqiqiy raqamlar haqida ko'proq ma'lumotni ushbu maqolada o'qishingiz mumkin . Ammo qabul qilinadigan diapazondan kattaroq raqamlarni saqlashimiz kerak bo'lsa-chi? Bunday holda, bizga kerak bo'ladi BigIntegerva BigDecimal.

Java-da BigInteger

Java klassi BigInteger64 bitli uzunlik chegarasiga ega bo'lmagan ixtiyoriy uzunlikdagi butun son qiymatlarining analogi sifatida ishlatiladi. NumberBundan tashqari, u oddiy raqamli turdagi - Integer, Long, Byte, Doubleva boshqalar uchun standart o'ramlar kabi sinfning avlodidir , shuning uchun u oddiy turlarga olib keladigan usullarni amalga oshiradi:
BigInteger value = new BigInteger("32145");

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

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

double doubleValue = value.doubleValue();//32145.0
Darhol biz bunday ob'ektning yaratilishini ko'ramiz, BigIntegerbizning qiymatimiz konstruktorga uzatiladi, lekin string formatida. Shuni ta'kidlash kerakki, uning bir nechta dizaynerlari bor, lekin barcha holatlar uchun. Agar ibtidoiy turlar ma'lumotlarning to'liq hajmini sig'dirmasa BigInteger, ma'lumotlar o'sha ibtidoiy turdagi diapazonga qisqartiriladi. Shu bilan birga, bu usullarning analoglari ( va boshqalar) mavjud bo'lib intValueExact(), longValueExact()yagona farq shundaki, agar konvertatsiya qilinayotgan oddiy tip ma'lumotlar oralig'iga mos kelmasa, ArithmeticException tashlanadi .

BigInteger konstantalari

Ichki foydalanish uchun sinfda doimiylar mavjud:
BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
Bular BigIntegermos ravishda, va qiymatlari bo'lgan 0doimiy ob'ektlardir . 110

BigInteger usullari

Bu sinfning asosiy xususiyatlaridan biri shundaki, u Java-da standart arifmetik amallarni amalga oshiradigan usullar bilan to'la. Masalan:
  • yig'ish operatsiyalari:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.add(secondValue);//73461
  • ko'paytirish operatsiyalari:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.multiply(secondValue);//1347530670
  • Bir sonni ikkinchisiga bo'lishda qoldiqni topish amallari:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.remainder(secondValue);//2529
  • raqamning mutlaq qiymatini olish (ya'ni modul, imzosiz):

    BigInteger firstValue = new BigInteger("-37995");
    BigInteger resultValue =  firstValue.abs();//37995
Bundan tashqari, murakkab (o'ziga xos) operatsiyalar uchun usullar mavjud:
  • mod hisoblash bilan operatsiyalar :

    BigInteger firstValue = new BigInteger("-34");
    BigInteger secondValue = new BigInteger("5");
    BigInteger resultValue = firstValue.mod(secondValue); //1
Ushbu funktsiyaning turli xil variantlari mavjud:
  • tasodifiy sonni olish va natijada olingan qiymat foydalanadigan bitlar sonini belgilash:

    BigInteger firstValue = BigInteger.probablePrime(8, new Random());//211
    BigInteger secondValue = BigInteger.probablePrime(16, new Random());//42571
  • bit bo'yicha siljish operatsiyalari (bu >> n)

    Chapga siljitish:

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

    O'ngga siljitish:

    BigInteger secondValue = new BigInteger("34");
    BigInteger secondResultValue = secondValue.shiftRight(2); //8
Albatta, hujjatlarda usullarning to'liq ro'yxatini ko'rib chiqish yaxshiroqdir . BigInteger va BigDecimal - 2

Java-da BigDecimal

Bizga ixtiyoriy uzunlikning haqiqiy soni kerak bo'lganda, Java klassi ishlatiladi - BigDecimal. Qoida tariqasida, u o'rniga moliya bilan ishlash uchun ishlatiladi double, chunki u ko'proq moslashtirish imkoniyatlarini beradi. Like va BigInteger, BigDecimalsinfning avlodidir Numberva ob'ekt qiymatini o'ziga xos ibtidoiy tip sifatida qaytaradigan usullarga ega:
BigDecimal value = new BigDecimal(35563.3);

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

double doubleValue = value.doubleValue();//35563.3
ga qisqartirishda ko'rib turganimizdek long, faqat butun qism qoladi va kasrlar o'chiriladi.

BigDecimal konstruktorlari

Biz konstruktorlarni batafsil ko'rib chiqamiz BigDecimal, chunki sinfda ularning tanlovi ancha kengroq. Ob'ektning qiymatini turli yo'llar bilan ( int, long, double, Stringva hatto ni o'tkazish orqali BigInteger) o'rnatishga imkon beruvchi konstruktorlar va ruxsat beruvchilar mavjud. yaratilgan ob'ekt sozlamalarini o'rnating (yaxlitlash usullari, kasr soni):
BigDecimal firstValue = new BigDecimal("455656.545");//455656.545
Bu erda hamma narsa aniq, biz to'g'ridan-to'g'ri biz ko'rmoqchi bo'lgan kasrlarning qiymatini va sonini o'rnatamiz.
BigDecimal secondValue = new BigDecimal(3445.54);//3445.5399999999999636202119290828704833984375
Ushbu konstruktorning natijalari oldindan aytib bo'lmaydigan bo'lishi mumkin, chunki biz o'z tabiatiga ko'ra juda noaniq turni ko'rsatmoqdamiz. Shuning uchun odatda konstruktorda foydalanish tavsiya etiladi String.
BigDecimal thirdValue = new BigDecimal(3445.554645675444, MathContext.DECIMAL32);//3445.555
Biz o'rnatdik double, lekin ayni paytda yaxlitlash qoidasini tavsiflovchi parametrni ham o'rnatamiz (u o'nli kasrlar sonini va yaxlitlash algoritmini o'z ichiga oladi).
char[] arr = new String("455656.545").toCharArray();

BigDecimal fourthValue = new BigDecimal(arr, 2, 6);//5656.5
Biz ob'ekt uchun qiymatlarni qaysi elementdan olishimiz va ushbu elementlardan qanchasini olishimiz uchun belgilar qatorini o'rnatamiz.
BigDecimal fifthValue = new BigDecimal(new BigInteger("44554"), 3);//44.554
Biz allaqachon mavjud bo'lgan ob'ektni olamiz BigInteger, o'nli kasr sonini o'rnatamiz.

BigDecimal usullari

Sinfda BigDecimalturli arifmetik amallar uchun usullar ham mavjud, ammo BigIntegerunda bitlar bilan ishlash usullari mavjud emas, masalan. Ammo shunga qaramay, asosiy xususiyat BigDecimalsuzuvchi nuqta raqamlari bilan ishlashda moslashuvchanlikdir. Keling, haqiqiy raqamlarni o'zlashtirishga imkon beradigan ba'zi texnikalarni ko'rib chiqaylik:
  • Biz aniqlikni olamiz (raqamlar soni):

    BigDecimal value = new BigDecimal("454334.34334");
    int result = value.precision();//11
  • kasr sonini va yaxlitlash qoidasini belgilang:

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

    Quyida yaxlitlash qoidalarini o'rnatish uchun konstantalarni batafsil ko'rib chiqamiz.

  • kerakli o'nli kasrlar sonini va yaxlitlash qoidasini ko'rsatgan holda BigDecimalboshqasiga bo'ling :BigDecimal

    BigDecimal firstValue = new BigDecimal("455656.545");
    
    BigDecimal secondValue = new BigDecimal(3445.544445);
    
    BigDecimal result = firstValue.divide(secondValue, 2,RoundingMode.DOWN);//132.24
  • kasr nuqtasini ma'lum miqdordagi o'ngga/chapga siljitish:

    BigDecimal value = new BigDecimal("455656.545");
    BigDecimal firstResult = value.movePointRight (2);//45565654.5
    BigDecimal secondResult = value.movePointLeft (2);//4556.56545
  • orqadagi nollarni kesish:

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

    Agar bizda haqiqiy qismda barcha nollar bo'lsa va butun qismda ham nollar bo'lsa (yoki bizda o'nlik kasrlar yo'q), unda:

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

BigDecimal yaxlitlash qoidalari

Yaxlitlash qoidalarini o'rnatish uchun ichkarida BigDecimalyaxlitlash algoritmlarini tavsiflovchi maxsus konstantalarni ko'rishimiz mumkin: ROUND_UP- noldan yaxlitlash, haqiqiy qismga yaxlitlash:
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— nolga yaxlitlash, ya'ni haqiqiy qismni qisqartirish:
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— ijobiy cheksizlikka yaxlitlash. Ya'ni, agar raqamimiz ijobiy bo'lsa, u holda -> ROUND_UP, manfiy bo'lsa, ->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- manfiy cheksizlikka yaxlitlash, ya'ni sonimiz musbat bo'lsa -> ROUND_DOWN, manfiy bo'lsa ->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
Ko'rib chiqilayotgan qiymat uchun biz kesilgan kasrli eng yaqin raqamni ko'rib chiqilayotgan raqamning eng yaqin qo'shnisi sifatida ko'rib chiqamiz. Misol uchun, 2,43 2,5 dan 2,4 ga yaqinroq bo'ladi, lekin 2,48 2,5 ga yaqinroq bo'ladi. ROUND_HALF_DOWN— “yaqin qo‘shni”ga yaxlitlash. Agar ikkala qo'shni ham ma'lum bir qiymatdan teng masofada bo'lsa, u holda nolga yaxlitlash amalga oshiriladi. Teng masofa, masalan, yaxlitlanadigan raqam 5 bo'lsa va u 0 va 10 dan bir xil masofada bo'lsa):
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— "yaqin qo'shni" tomon yaxlitlash rejimi. Ikkala qo'shni ham bir xil masofada bo'lsa, yaxlitlash amalga oshiriladi (bu bizga maktabda o'rgatilgan yaxlitlashdir):
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- agar ikkala qo'shni ham bir xil masofada bo'lmasa, "eng yaqin qo'shni" ga yaxlitlash. Bunda yaxlitlanayotgan sondan oldin toq son bo‘lsa, u yuqoriga, juft bo‘lsa, pastga yaxlitlanadi:
BigDecimal firstValue = new BigDecimal("2222.2225");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.222
Biz bu natijani olamiz, chunki yaxlitlashda 5 oldingi 2 raqamiga qaraydi va uning juft ekanligini ko'rib, pastga yaxlitlanadi. Ammo agar:
BigDecimal firstValue = new BigDecimal("2222.22255");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.223
Bu yaxlitlash yuqoriga ko'tariladi, chunki oxirgi 5 oldingi qiymatga qaraydi va toq raqamni ko'radi. Natijada, raqam 6 ga yaxlitlanadi, undan keyin keyingi 6 ham yaxlitlanadi. Ammo oltitasi endi chapdagi raqamga qaramaydi, chunki raqam yuqoriga aniq yaqinroq bo'ladi va natijada oxirgi 2 1 ga ko'payadi. ROUND_UNNECESSARY- raqamni yaxlitlash shart emasligini tekshirish uchun ishlatiladi. Ya'ni, raqamda kerakli o'nlik kasrlar mavjudligini tekshiramiz:
BigDecimal firstValue = new BigDecimal("2.55");
BigDecimal firstResult =  firstValue.setScale(2, BigDecimal.ROUND_UNNECESSARY);//2.55
Bu erda hamma narsa yaxshi, qiymat ikki raqamga ega va biz kasrdan keyin faqat ikkita raqam borligini tekshiramiz. Ammo agar:
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UNNECESSARY);
Keyin biz - ni olamiz ArithmeticException, chunki tekshirilayotgan qiymat belgilangan kasr sonidan oshadi. Ammo agar biz ikkita kasrli kasrni tekshirsak, lekin u erda bitta bo'lsa, unda istisno bo'lmaydi va etishmayotgan raqamlar shunchaki nol bilan to'ldiriladi:
BigDecimal thirdValue = new BigDecimal("2.5");
BigDecimal thirdResult = thirdValue.setScale(3, BigDecimal.ROUND_UNNECESSARY   );//2.500
Shuni ham ta'kidlashni istardimki, y ning doimiylarga BigDecimalo'xshash doimiylari bor BigInteger ZEROva ONE. Bu erda hujjatlargaTEN havola . Va nihoyat: siz sezganingizdek, ob'ektlar bilan operatsiyalarni bajarishda va , biz eskilarini o'zgartirmaymiz, balki har doim yangilarini olamiz. Bu ularning , ya'ni yaratilganidan keyin o'zgarmasligini, xuddi . Boshqacha qilib aytadigan bo'lsak, ularning barcha usullari ob'ektning ichki holatini o'zgartira olmaydi, ko'pi bilan biz foydalanayotgan funksiya tomonidan ko'rsatilgan parametrlarga ega yangi ob'ektni qaytarishi mumkin. BigIntegerBigDecimalimmutableString
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION