ประเภทดั้งเดิม | ขนาดในหน่วยความจำ | ช่วงของค่า |
---|---|---|
ไบต์ | 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