סוג פרימיטיבי | גודל בזיכרון | טווח ערכים |
---|---|---|
בייט | 8 ביט | -128 עד 127 |
קצר | 16 ביט | ל-32768 עד 32767 |
לְהַשְׁחִיר | 16 ביט | מ-0 ל-65536 |
int | 32 ביטים | מ-2147483648 ל-2147483647 |
ארוך | 64 ביטים | מ-9223372036854775808 ל-9223372036854775807 |
לָצוּף | 32 ביטים | מ-(2 בחזקת -149) ל-((2-2 בחזקת -23)*2 בחזקת 127) |
לְהַכפִּיל | 64 ביטים | מ-(-2 בחזקת 63) ל-((2 בחזקת 63) - 1) |
בוליאני | 8 (בשימוש במערכים), 32 (בשימוש בלא-מערכים) | אמת או שקר |
BigInteger
הוא BigDecimal
כמעט בלתי מוגבל. למה משמשים השיעורים האלה? קודם כל לחישובים עם דרישות דיוק גבוהות במיוחד. יש, למשל, תוכנות שבהן חיי אדם יכולים להיות תלויים בדיוק של חישובים (תוכנה למטוסים ורקטות או לציוד רפואי). לכן, אם אפילו המקום ה-150 העשרוני משחק תפקיד חשוב, BigDecimal
זו הבחירה הטובה ביותר. בנוסף, לעתים קרובות נעשה שימוש בחפצים אלה בעולם הפיננסים, שבו דיוק החישובים עד לערכים הקטנים ביותר הוא גם חשוב ביותר. איך עובדים עם חפצים BigInteger
ומה BigDecimal
חשוב לזכור לגביהם? אובייקטים של מחלקות אלה נוצרים כך:
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);
}
}
העברת מחרוזת כפרמטר היא רק אחד מהבנאים האפשריים. כאן אנחנו משתמשים במחרוזות כי המספרים שלנו חורגים מהערכים המקסימליים long
ו- double
, ואיכשהו אנחנו צריכים להסביר למהדר בדיוק איזה מספר אנחנו רוצים לקבל :) פשוט תעביר את המספר 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111. 1111111 לא יעבוד: Java תנסה "להתאים" המספר שהועבר לאחד מסוגי הנתונים הפרימיטיביים, אך הוא לא יתאים לאף אחד מהם. לכן, שימוש במחרוזת כדי להעביר את המספר הרצוי היא אפשרות טובה. שתי המחלקות יכולות לחלץ באופן אוטומטי ערכים מספריים ממחרוזות שעברו. נקודה חשובה נוספת שכדאי לזכור כשעובדים עם מחלקות מספר גדול היא שהאובייקטים שלהן בלתי ניתנים לשינוי ( Immutable
) . אתה כבר מכיר היטב את עקרון הבלתי משתנה מהדוגמה של מחלקה String
ושיעורי עיטוף לפרימיטיביים (Integer, Long ואחרים).
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);
}
}
פלט מסוף:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
המספרים שלנו לא השתנו, כפי שהיית מצפה. כדי שפעולת ההוספה תצליח, עליך ליצור אובייקט חדש ולהקצות לו את תוצאת התוספת.
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);
}
}
פלט מסוף:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
עכשיו הכל עובד כמו שצריך :) אגב, שמתם לב עד כמה פעולת התוספת נראית יוצאת דופן?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
זו עוד נקודה חשובה. מחלקות מספר גדול אינן משתמשות באופרטורים +-*/ בפעולתן, אלא מספקות קבוצה של שיטות. בואו נסתכל על העיקריות שבהן (תוכלו, כמו תמיד, למצוא רשימה מלאה של שיטות בתיעוד של אורקל: כאן וכאן ) .
-
שיטות לביצוע פעולות אריתמטיות:
add()
,subtract()
,multiply()
,divide()
. משמש לפעולות חיבור, חיסור, כפל וחילוק בהתאמה. -
doubleValue()
,intValue()
,floatValue()
,longValue()
וכו. - משמש להמרת מספר גדול לסוג פרימיטיבי של Java. היזהר בעת השימוש בהם וזכור את ההבדל בקיבולת!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); } }
פלט מסוף:
8198552921648689607
-
min()
וכןmax()
- לאפשר לך למצוא את הערך המינימלי והמקסימלי של שני מספרים גדולים שעברו.
שימו לב: השיטות אינן סטטיות!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)); } }
פלט מסוף:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
בקרת עיגול BigDecimal
נושא זה נכלל בסעיף נפרד, שכן עיגול מספרים גדולים והתאמתם אינם דבר כה פשוט. אתה יכול להגדיר את מספר המקומות העשרוניים עבור מספרBigDecimal
באמצעות setScale()
. לדוגמה, אנו רוצים להגדיר את הדיוק של המספר 111.5555555555 לשלושה מקומות עשרוניים. עם זאת, לא נוכל להעביר את המספר 3 כטיעון לשיטה setScale()
ובכך לפתור את הבעיה שלנו. כפי שהוזכר לעיל, BigDecimal
אלו הם מספרים לחישובים בעלי דיוק מוגבר. בצורתו הנוכחית, למספר שלנו יש 10 מקומות עשרוניים. אנחנו רוצים להשליך 7 מהם ולהשאיר רק 3. לכן, בנוסף למספר 3, עלינו להעביר את מצב העיגול כפרמטר . ישנם 8 מצבי עיגול בסך הכל BigDecimal
. די הרבה! אבל אם אתה צריך באמת לכוונן את הדיוק של החישובים בתוכנית, יהיה לך כל מה שאתה צריך בשביל זה. אז הנה 8 מצבי העיגול הזמינים ב BigDecimal
:
-
ROUND_CEILING
- מעגל111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN
- השלכת פריקה111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR
- עיגול למטה111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP
— עיגול כלפי מעלה אם המספר אחרי הנקודה העשרונית >= .50.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN
— עיגול כלפי מעלה אם המספר אחרי הנקודה העשרונית > .50.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN
- עיגול יהיה תלוי במספר שמשמאל לנקודה העשרונית. אם המספר משמאל הוא זוגי, העיגול יתבצע כלפי מטה. אם המספר משמאל לנקודה העשרונית הוא אי זוגי, הוא יעוגל כלפי מעלה.2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
המספר משמאל לנקודה העשרונית - 2 - זוגי. העיגול מתרחש כלפי מטה. מכיוון שאנו דורשים 0 מקומות עשרוניים, התוצאה תהיה 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
המספר משמאל לנקודה העשרונית - 3 - הוא אי זוגי. עיגול מתרחש כלפי מעלה. מכיוון שאנו דורשים 0 מקומות עשרוניים, התוצאה תהיה 4.
-
ROUND_UNNECCESSARY
- משמש במקרים שבהם יש להעביר את מצב העיגול לשיטה כלשהי, אך אין צורך לעגל את המספר. אם תנסה לעגל מספר כאשר מצב ROUND_UNNECCESSARY מוגדר, נזרק חריגה אריתמטית.3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP
- מעגל.111.5551 -> setScale(3, ROUND_UP) -> 111.556
השוואה של מספרים גדולים
גם שאלה זו חשובה. אתה כבר זוכר שהשיטה משמשת להשוואת אובייקטים ב-Javaequals()
. זה מסופק על ידי השפה עצמה (במקרה של מחלקות מובנות של Java) או מעקף על ידי המתכנת. אבל במקרה של אובייקטי מחלקה, לא מומלץ BigDecimal
להשתמש בשיטה equals()
לצורך השוואה. הסיבה לכך היא ששיטת BigDecimal.equals()
שני המספרים מחזירה אמת רק אם לשני המספרים יש אותו ערך וקנה מידה : בואו נשווה את ההתנהגות של שיטות equals()
y Double
ו-y BigDecimal
:
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));
}
}
פלט מסוף:
true
false
כפי שאתה יכול לראות, המספרים 1.5 ו-1.50 במקרה של c BigDecimal
התבררו כלא שווים! זה קרה בדיוק בגלל הפרטים של השיטה equals()
בכיתה BigDecimal
. להשוואה נכונה יותר של השניים, BigDecimal
עדיף להשתמש בשיטה compareTo()
:
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));
}
}
פלט מסוף:
0
השיטה compareTo()
החזירה 0, כלומר שווה ל-1.5 ו-1.50. זו התוצאה שציפינו עליה! :) זה מסיים את השיעור שלנו להיום. הגיע הזמן לחזור למשימות! :)
GO TO FULL VERSION