ב-Java, אפליקציה מורכבת ממחלקות, ומחלקות מורכבות משיטות ומשתנים. משתנים, בתורם, מחולקים לפרימיטיבי ולהתייחסות. ישנם 8 סוגים של משתנים ב-Java, ולמעט
boolean
ו- char
, הם מחולקים לסוגים הבאים:
- מספרים שלמים:
byte
,short
,int
וlong
; - נקודה צפה (נקראת גם מספרים ממשיים):
float
וdouble
.
long
, עם טווח מ-9223372036854775808 עד 9223372036854775807. מבין מספרי הנקודה הצפה, , double
עם טווח של 1.7e-308 עד 1.7e+308. אתה יכול לקרוא עוד על מספרים אמיתיים במאמר זה . אבל מה אם נצטרך לאחסן מספרים גדולים מהטווח המקובל? במקרה זה, נצטרך BigInteger
ו BigDecimal
.
BigInteger ב-Java
מחלקת JavaBigInteger
משמשת כאנלוגי לערכי מספרים שלמים באורך שרירותי שאין להם מגבלת 64 סיביות של ארוך. יתר על כן, הוא צאצא של המחלקה Number
, כמו עטיפות סטנדרטיות לסוגים מספריים פשוטים - Integer
, Long
, Byte
, Double
וכן הלאה - ולכן יש לה יישומים של שיטות המובילות לסוגים פשוטים:
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.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
-
קבלת הערך המוחלט של מספר (כלומר, modulo, unsigned):
BigInteger firstValue = new BigInteger("-37995"); BigInteger resultValue = firstValue.abs();//37995
-
פעולות עם חישוב מוד :
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
BigDecimal ב-Java
כאשר אנו זקוקים למספר ממשי באורך שרירותי, נעשה שימוש במחלקת Java -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.4 מ-2.5, אך 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
. במילים אחרות, כל השיטות שלהם לא יכולות לשנות את המצב הפנימי של האובייקט; לכל היותר, הן יכולות להחזיר אובייקט חדש עם הפרמטרים שצוינו על ידי הפונקציה שבה אנו משתמשים.
GO TO FULL VERSION