JavaRush /وبلاگ جاوا /Random-FA /BigInteger و BigDecimal

BigInteger و BigDecimal

در گروه منتشر شد
در جاوا یک برنامه از کلاس ها و کلاس ها از متدها و متغیرها تشکیل شده است. متغیرها به نوبه خود به ابتدایی و مرجع تقسیم می شوند. BigInteger و BigDecimal - 18 نوع متغیر در جاوا وجود دارد که به استثنای booleanو charبه انواع زیر تقسیم می شوند:
  • اعداد صحیح : byte, shortو ;intlong
  • ممیز شناور (که اعداد حقیقی نیز نامیده می شود): floatو double.
در این گروه‌های کوچک، تفاوت‌ها فقط در محدوده مقادیری وجود دارد که می‌توان آنها را در نظر گرفت (و بر این اساس، فضای اشغال شده چنین متغیری متفاوت است). بزرگترین نوع اعداد صحیح longبا دامنه ای از 9223372036854775808- تا 9223372036854775807 است double. در این مقاله می توانید اطلاعات بیشتری در مورد اعداد واقعی بخوانید . اما اگر نیاز به ذخیره اعداد بزرگتر از محدوده قابل قبول داشته باشیم، چه؟ در این صورت به BigIntegerو BigDecimal.

BigInteger در جاوا

کلاس جاوا BigIntegerبه عنوان یک آنالوگ برای مقادیر اعداد صحیح با طول دلخواه استفاده می شود که محدودیت 64 بیتی طولانی را ندارد. علاوه بر این، این یک از نوادگان کلاس است ، مانند لفاف‌های استاندارد برای انواع Numberساده عددی - Integer،،، و غیره - بنابراین دارای پیاده‌سازی روش‌هایی است که منجر به انواع ساده می‌شوند: LongByteDouble
BigInteger value = new BigInteger("32145");

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

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

double doubleValue = value.doubleValue();//32145.0
بلافاصله شاهد ایجاد چنین شیئی هستیم BigIntegerکه مقدار ما به سازنده منتقل می شود، اما در قالب رشته. شایان ذکر است که او بیش از یک طراح دارد، اما برای همه موارد. اگر انواع اولیه کل مقدار داده را در خود جای ندهند BigInteger، داده ها به محدوده آن نوع اولیه کوتاه می شوند. اما در عین حال، مشابه‌هایی از این روش‌ها (و غیره) وجود دارد intValueExact()، longValueExact()تنها با این تفاوت که اگر نوع ساده‌ای که تبدیل به آن انجام می‌شود، محدوده داده‌ها را تطبیق ندهد، یک ArithmeticException پرتاب می‌شود .

ثابت های BigInteger

برای استفاده داخلی، کلاس دارای ثابت هایی است:
BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
اینها اشیاء ثابت BigIntegerبا مقادیر، به ترتیب 0، 1و 10.

روش های BigInteger

یکی از ویژگی های اصلی این کلاس این است که پر از متدهایی است که عملیات حسابی استاندارد را در جاوا پیاده سازی می کنند. مثلا:
  • عملیات جمع بندی:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.add(secondValue);//73461
  • عملیات ضرب:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.multiply(secondValue);//1347530670
  • عملیات یافتن باقیمانده هنگام تقسیم یک عدد بر عدد دیگر:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.remainder(secondValue);//2529
  • گرفتن قدر مطلق یک عدد (یعنی مدول، بدون علامت):

    BigInteger firstValue = new BigInteger("-37995");
    BigInteger resultValue =  firstValue.abs();//37995
همچنین روش هایی برای عملیات پیچیده تر (خاص) وجود دارد:
  • عملیات با محاسبه mod :

    BigInteger firstValue = new BigInteger("-34");
    BigInteger secondValue = new BigInteger("5");
    BigInteger resultValue = firstValue.mod(secondValue); //1
چندین نوع مختلف از این تابع وجود دارد:
  • به دست آوردن یک عدد تصادفی و تعیین تعداد بیت هایی که مقدار حاصل از آن استفاده می کند:

    BigInteger firstValue = BigInteger.probablePrime(8, new Random());//211
    BigInteger secondValue = BigInteger.probablePrime(16, new Random());//42571
  • عملیات شیفت بیتی (این >> n)

    جابجایی به چپ:

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

    جابجایی به راست:

    BigInteger secondValue = new BigInteger("34");
    BigInteger secondResultValue = secondValue.shiftRight(2); //8
البته بهتر است به لیست کامل روش ها در مستندات نگاه کنید . BigInteger و BigDecimal - 2

BigDecimal در جاوا

زمانی که به تعداد واقعی طول دلخواه نیاز داریم، کلاس جاوا استفاده می شود - BigDecimal. به عنوان یک قاعده، از آن برای کار با امور مالی به جای استفاده می شود double، زیرا گزینه های سفارشی سازی بیشتری را ارائه می دهد. Like و BigInteger, BigDecimalاز نسل یک کلاس است Numberو متدهایی دارد که مقدار یک شی را به عنوان یک نوع اولیه خاص برمی گرداند:
BigDecimal value = new BigDecimal(35563.3);

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

double doubleValue = value.doubleValue();//35563.3
همانطور که می بینیم هنگام کاهش به long، فقط قسمت عدد صحیح باقی می ماند و اعداد اعشار کنار گذاشته می شوند.

سازنده های BigDecimal

ما نگاهی دقیق تر به سازنده ها خواهیم داشت BigDecimal، زیرا کلاس انتخاب بسیار گسترده تری از آنها دارد. سازنده هایی وجود دارند که به شما امکان می دهند مقدار یک شی را به روش های مختلف تنظیم کنید (با عبور از int, long, double, Stringو حتی BigInteger) و مواردی هم هستند که اجازه می دهند. تنظیمات شی ایجاد شده را تنظیم کنید (روش های گرد کردن، تعداد ارقام اعشار):
BigDecimal firstValue = new BigDecimal("455656.545");//455656.545
اینجا همه چیز واضح است، ما مستقیماً مقدار و تعداد ارقام اعشاری را که می خواهیم ببینیم تنظیم می کنیم.
BigDecimal secondValue = new BigDecimal(3445.54);//3445.5399999999999636202119290828704833984375
نتایج این سازنده می تواند کاملاً غیرقابل پیش بینی باشد، زیرا ما دوگانه را مشخص می کنیم که طبیعتاً یک نوع بسیار مبهم است. بنابراین، به طور کلی توصیه می شود که در یک سازنده استفاده شود String.
BigDecimal thirdValue = new BigDecimal(3445.554645675444, MathContext.DECIMAL32);//3445.555
ما تنظیم می کنیم double، اما در عین حال پارامتری را نیز تنظیم می کنیم که قانون گرد کردن (که شامل تعداد ارقام اعشار و الگوریتم گرد کردن است) را توصیف می کند.
char[] arr = new String("455656.545").toCharArray();

BigDecimal fourthValue = new BigDecimal(arr, 2, 6);//5656.5
ما یک آرایه از کاراکترها را تنظیم می کنیم که از کدام عنصر مقادیر شی را می گیریم و چه تعداد از این عناصر را می گیریم.
BigDecimal fifthValue = new BigDecimal(new BigInteger("44554"), 3);//44.554
یک شی از قبل موجود را می گیریم BigInteger، تعداد ارقام اعشار را تنظیم می کنیم.

روش های BigDecimal

این کلاس BigDecimalهمچنین حاوی متدهایی برای عملیات حسابی مختلف است، اما BigIntegerمتدهایی برای کار با بیت ها مانند . اما با این وجود، ویژگی اصلی BigDecimalانعطاف پذیری در کار با اعداد ممیز شناور است. بیایید به تکنیک هایی نگاه کنیم که به ما قدرت تسلط بر اعداد واقعی را می دهند:
  • دقت (تعداد اعداد) را بدست می آوریم:

    BigDecimal value = new BigDecimal("454334.34334");
    int result = value.precision();//11
  • تعداد ارقام اعشار و قانون گرد کردن را تنظیم کنید:

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

    در زیر نگاهی دقیق‌تر به ثابت‌های تنظیم قوانین گرد کردن خواهیم داشت.

  • تقسیم BigDecimalبر دیگری BigDecimal، در حالی که تعداد اعشار مورد نیاز و قانون گرد کردن را نشان می دهد:

    BigDecimal firstValue = new BigDecimal("455656.545");
    
    BigDecimal secondValue = new BigDecimal(3445.544445);
    
    BigDecimal result = firstValue.divide(secondValue, 2,RoundingMode.DOWN);//132.24
  • حرکت یک نقطه اعشار به راست/چپ با تعداد معینی مکان:

    BigDecimal value = new BigDecimal("455656.545");
    BigDecimal firstResult = value.movePointRight (2);//45565654.5
    BigDecimal secondResult = value.movePointLeft (2);//4556.56545
  • برش صفرهای انتهایی:

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

    اگر همه صفرها را در قسمت واقعی داشته باشیم و در کل قسمت نیز صفر باشد (یا اصلاً رقم اعشار نداریم)، ​​پس:

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

قوانین گرد کردن BigDecimal

برای تنظیم قوانین گرد کردن، BigDecimalمی‌توانیم ثابت‌های خاصی را ببینیم که الگوریتم‌های گرد کردن را توصیف می‌کنند: ROUND_UP- گرد کردن از صفر، گرد کردن به سمت قسمت واقعی:
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- گرد کردن به صفر، یعنی برش قسمت واقعی:
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- گرد شدن به بی نهایت مثبت. یعنی اگر عدد ما مثبت باشد -> ROUND_UPو اگر منفی باشد ->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- گرد کردن به بی نهایت منفی، یعنی اگر عدد ما مثبت باشد، پس -> ROUND_DOWN، اگر منفی است، پس ->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
برای مقدار مورد نظر، این نزدیکترین عدد را با رقم اعشار کوتاه به عنوان نزدیکترین همسایه عدد مورد بررسی در نظر می گیریم. برای مثال، 2.43 از 2.5 به 2.4 نزدیکتر خواهد شد، اما 2.48 به 2.5 نزدیکتر خواهد شد. ROUND_HALF_DOWN- گرد کردن به "نزدیکترین همسایه". اگر هر دو همسایه از یک مقدار خاص فاصله داشته باشند، دور به صفر انجام می شود. مساوی زمانی است که مثلاً عدد گرد شده 5 باشد و از 0 و 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- حالت برای گرد کردن به سمت "نزدیکترین همسایه". اگر هر دو همسایه با هم فاصله داشته باشند، جمع کردن به بالا انجام می شود (این همان گرد کردنی است که در مدرسه به ما آموزش داده شد):
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- اگر هر دو همسایه با هم فاصله نداشته باشند، به «نزدیکترین همسایه» گرد کنید. در این صورت، اگر قبل از عددی که گرد می شود عددی فرد باشد، به سمت بالا و اگر زوج باشد، به سمت پایین گرد می شود:
BigDecimal firstValue = new BigDecimal("2222.2225");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.222
این نتیجه را به این دلیل به دست می آوریم که هنگام گرد کردن، 5 به عدد 2 قبلی نگاه می کند و با دیدن زوج بودن آن، به سمت پایین گرد می شود. اما اگر:
BigDecimal firstValue = new BigDecimal("2222.22255");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.223
این گرد کردن بالا می رود، زیرا 5 آخر به مقدار قبلی نگاه می کند و یک عدد فرد را می بیند. در نتیجه عدد به 6 گرد می شود و پس از آن عدد 6 بعدی نیز گرد می شود. اما شش دیگر به عدد سمت چپ نگاه نمی کند، زیرا عدد به وضوح به سمت بالا نزدیکتر است و در نتیجه 2 آخر 1 افزایش می یابد. ROUND_UNNECESSARY- برای بررسی اینکه عدد نیازی به گرد کردن ندارد استفاده می شود. یعنی بررسی می کنیم که عدد دارای تعداد اعشار لازم باشد:
BigDecimal firstValue = new BigDecimal("2.55");
BigDecimal firstResult =  firstValue.setScale(2, BigDecimal.ROUND_UNNECESSARY);//2.55
اینجا همه چیز خوب است، مقدار دارای دو رقم است و بررسی می کنیم که فقط دو رقم بعد از نقطه اعشار وجود داشته باشد. اما اگر:
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UNNECESSARY);
سپس ما - را دریافت می کنیم ArithmeticException، زیرا مقدار مورد آزمایش از تعداد اعشار مشخص شده بیشتر است. اما اگر دو رقم اعشار را بررسی کنیم، اما در واقع یک رقم وجود دارد، استثنا پرتاب نمی شود و ارقام گمشده به سادگی با صفر تکمیل می شوند:
BigDecimal thirdValue = new BigDecimal("2.5");
BigDecimal thirdResult = thirdValue.setScale(3, BigDecimal.ROUND_UNNECESSARY   );//2.500
همچنین می‌خواهم توجه داشته باشم که y دارای BigDecimalثابت‌هایی شبیه به ثابت‌ها BigInteger ZEROو ONE. TENدر اینجا یک پیوند به مستندات است . و در نهایت: همانطور که احتمالاً متوجه شدید، هنگام انجام عملیات با اشیاء BigIntegerو BigDecimal, ما موارد قدیمی را تغییر نمی دهیم، بلکه همیشه موارد جدید دریافت می کنیم. این به ما می گوید که آنها immutableپس از خلقتشان تغییر ناپذیرند، درست مانند String. به عبارت دیگر، همه متدهای آن‌ها نمی‌توانند وضعیت داخلی شی را تغییر دهند؛ حداکثر می‌توانند یک شی جدید را با پارامترهای مشخص شده توسط تابع مورد استفاده ما برگردانند.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION