| ประเภทดั้งเดิม | ขนาดในหน่วยความจำ | ช่วงของค่า |
|---|---|---|
| ไบต์ | 8 บิต | -128 ถึง 127 |
| สั้น | 16 บิต | ถึง -32768 ถึง 32767 |
| ถ่าน | 16 บิต | ตั้งแต่ 0 ถึง 65536 |
| ภายใน | 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และอย่างใดเราต้องอธิบายให้คอมไพเลอร์ฟังว่าเราต้องการได้ตัวเลขอะไร :) เพียงแค่ส่งหมายเลข 1111111111111111111111111111111111111111111111111111111 ถึงผู้สร้าง 11111111111111111111111111111111111111111111111111111111111111111111 จะไม่ทำงาน: Java จะพยายาม “พอดี” ตัวเลขที่ส่งผ่านเป็นประเภทข้อมูลพื้นฐานประเภทใดประเภทหนึ่ง แต่จะไม่พอดีกับประเภทใดประเภทหนึ่ง ดังนั้นการใช้สตริงเพื่อส่งผ่านหมายเลขที่ต้องการจึงเป็นทางเลือกที่ดี ทั้งสองคลาสสามารถดึงค่าตัวเลขจากสตริงที่ส่งผ่านได้โดยอัตโนมัติ จุดสำคัญอีกจุดที่ต้องจำเมื่อทำงานกับคลาสจำนวนมากคืออ็อบเจ็กต์ของคลาสนั้นไม่เปลี่ยนรูป ( Immutable) คุณคุ้นเคยกับหลักการของความไม่เปลี่ยนรูปเป็นอย่างดีแล้วผ่านตัวอย่างของคลาสStringและคลาส wrapper สำหรับพื้นฐาน (จำนวนเต็ม ยาว และอื่นๆ)
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)); นี่เป็นอีกจุดสำคัญ คลาสจำนวนมากไม่ได้ใช้ตัวดำเนินการ +-*/ ในการดำเนินการ แต่จะจัดเตรียมชุดของวิธีการแทน มาดูหลักๆ กัน (คุณสามารถค้นหารายการวิธีการทั้งหมดในเอกสารประกอบของ Oracle เช่นเคย: ที่นี่และที่นี่ )
-
วิธีการดำเนินการทางคณิตศาสตร์:
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 ไว้ ArithmeticException จะถูกส่งออกไป3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException -
ROUND_UP- ปัดเศษขึ้น111.5551 -> setScale(3, ROUND_UP) -> 111.556
การเปรียบเทียบตัวเลขจำนวนมาก
คำถามนี้ก็มีความสำคัญเช่นกัน คุณจำได้แล้วว่าวิธีนี้ใช้ในการเปรียบเทียบวัตถุในequals()Java มันถูกจัดเตรียมโดยภาษาเอง (ในกรณีของคลาสในตัวของ 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