ประเภทดึกดำบรรพ์ | ขนาดในหน่วยความจำ | ช่วงค่า |
---|---|---|
ไบต์ | 8 บิต | -128 ถึง 127 |
สั้น | 16 บิต | -32768 ถึง 32767 |
ถ่าน | 16 บิต | 0 ถึง 65536 |
นานาชาติ | 32 บิต | -2147483648 ถึง 2147483647 |
ยาว | 64 บิต | -9223372036854775808 ถึง 9223372036854775807 |
ลอย | 32 บิต | (2 ยกกำลัง -149) ถึง ((2 ยกกำลัง -23) * 2 ยกกำลัง 127) |
สองเท่า | 64 บิต | (-2 ยกกำลัง 63) ถึง ((2 ยกกำลัง 63) - 1) |
บูลีน | 8 (เมื่อใช้ในอาร์เรย์), 32 (เมื่อไม่ได้ใช้ในอาร์เรย์) | จริงหรือเท็จ |
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และเราต้องการวิธีอธิบายให้คอมไพเลอร์ทราบว่าเราต้องการสร้างหมายเลขใด :) เพียงแค่ส่งหมายเลข 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ให้กับตัวสร้างจะไม่ทำงาน: Java จะพยายามยัดหมายเลขที่ส่งผ่านไปยังหนึ่งในประเภทข้อมูลดั้งเดิม แต่จะไม่พอดีกับประเภทใดเลย นั่นเป็นเหตุผลที่การใช้สตริงเพื่อส่งหมายเลขที่ต้องการจึงเป็นตัวเลือกที่ดี ทั้งสองคลาสสามารถแยกค่าตัวเลขจากสตริงที่ส่งผ่านได้โดยอัตโนมัติ จุดสำคัญอีกประการที่ต้องจำเมื่อทำงานกับคลาสที่มีจำนวนมากคือ คุณคุ้นเคยกับการเปลี่ยนแปลงไม่ได้แล้ว เนื่องจากประสบการณ์ของคุณกับ คลาส Stringและคลาส wrapper สำหรับประเภทดั้งเดิม (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);
}
}
เอาต์พุตคอนโซล:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
อย่างที่คุณคาดไว้ หมายเลขของเราไม่เปลี่ยนแปลง คุณต้องสร้างวัตถุใหม่เพื่อรับผลลัพธ์ของการดำเนินการ
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);
}
}
เอาต์พุตคอนโซล:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
ดูสิตอนนี้ทุกอย่างทำงานได้ตามปกติ :) คุณสังเกตเห็นว่าการดำเนินการเพิ่มมีลักษณะผิดปกติหรือไม่?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
นี่เป็นอีกจุดสำคัญ คลาสตัวเลขจำนวนมากไม่ใช้ตัวดำเนินการ + - * / แต่จะมีชุดของวิธีการแทน มาทำความคุ้นเคยกับวิธีหลัก (เช่นเคย คุณสามารถดูรายการวิธีการทั้งหมดได้ในเอกสารประกอบของ Oracle: ที่นี่และที่นี่ )
-
วิธีการดำเนินการทางคณิตศาสตร์: บวก() , ลบ() , คูณ() , หาร( ) วิธีการเหล่านี้ใช้ในการบวก ลบ คูณ และหารตามลำดับ
-
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
หัวข้อนี้มีส่วนแยกต่างหาก เนื่องจากการปัดเศษตัวเลขจำนวนมากและการกำหนดค่าลักษณะการปัดเศษนั้นไม่ง่ายนัก คุณสามารถใช้ เมธอด setScale ()เพื่อกำหนดจำนวนตำแหน่งทศนิยมสำหรับBigDecimal ตัวอย่างเช่น สมมติว่าเราต้องการให้หมายเลข111.5555555555มีตัวเลขหลังจุดทศนิยมสามหลัก อย่างไรก็ตาม เราไม่สามารถบรรลุสิ่งที่ต้องการได้โดยการส่งเลข 3 เป็นอาร์กิวเมนต์ไปยังเมธอดsetScale () ตามที่กล่าวไว้ข้างต้นBigDecimalมีไว้สำหรับแสดงตัวเลขที่มีข้อกำหนดเข้มงวดเกี่ยวกับความแม่นยำในการคำนวณ ในรูปแบบปัจจุบัน ตัวเลขของเรามี 10 หลักหลังจุดทศนิยม เราต้องการทิ้ง 7 รายการและเก็บไว้เพียง 3 ดังนั้นนอกเหนือจากหมายเลข 3 แล้วเราต้องผ่านโหมดการปัดเศษ BigDecimalมีโหมดการปัดเศษทั้งหมด 8 โหมด เยอะมาก! แต่ถ้าคุณต้องการปรับความแม่นยำของการคำนวณอย่างละเอียดจริงๆ คุณจะมีทุกสิ่งที่คุณต้องการ ดังนั้นนี่คือโหมดการปัดเศษ 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 — ปัดขึ้นถ้าตัวเลขหลังจุดทศนิยม >= 0.5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — ปัดขึ้นถ้าตัวเลขหลังจุดทศนิยม > 0.5
0.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 ระบบจะส่ง ArithmeticException
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — ปัดเศษออกจากศูนย์
111.5551 -> setScale(3, ROUND_UP) -> 111.556
เทียบเบอร์ใหญ่
นี่เป็นสิ่งสำคัญเช่นกัน คุณจะจำได้ว่าเราใช้เท่ากับ ()วิธีการเปรียบเทียบวัตถุใน Java การใช้งานนั้นมาจากตัวภาษาเอง (สำหรับคลาส Java มาตรฐาน) หรือถูกแทนที่โดยโปรแกรมเมอร์ แต่ในกรณีของวัตถุBigDecimalไม่แนะนำให้ใช้วิธีการเท่ากับ () สำหรับการเปรียบเทียบ นี่เป็นเพราะ เมธอด BigDecimal.equals()คืนค่าจริงก็ต่อเมื่อตัวเลข 2 ตัวมีค่าและสเกลเท่ากัน ลองเปรียบเทียบพฤติกรรมของเมธอดเท่ากับ()สำหรับ คลาส Doubleและ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
อย่างที่คุณเห็นสำหรับBigDecimalตัวเลข 1.5 และ 1.50 ไม่เท่ากัน! นี่เป็นเพราะความเฉพาะเจาะจงของการใช้ วิธี เท่ากับ ()ในคลาสBigDecimal สำหรับการเปรียบเทียบ วัตถุ BigDecimal สองวัตถุที่แม่นยำยิ่งขึ้น ควรใช้ วิธี การเปรียบเทียบถึง() :
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
วิธี การ เปรียบเทียบ ()คืนค่า 0 ซึ่งหมายความว่า 1.5 และ 1.50 เท่ากัน และนี่คือผลลัพธ์ที่เราคาดไว้! :) นั่นคือการสรุปบทเรียนของเราในวันนี้ ตอนนี้ได้เวลากลับไปทำงานแล้ว! :)