ตามที่คนอื่นพูดถึงคุณอาจต้องการใช้BigDecimal
ชั้นเรียนถ้าคุณต้องการให้มีตัวแทน 11.4 ที่แน่นอน
ตอนนี้มีคำอธิบายเล็กน้อยว่าทำไมสิ่งนี้จึงเกิดขึ้น:
float
และdouble
ดั้งเดิมประเภทใน Java เป็นจุดลอยตัวเลขจำนวนที่ถูกเก็บไว้เป็นตัวแทนของไบนารีส่วนและตัวแทน
โดยเฉพาะอย่างยิ่งค่าทศนิยมที่มีความแม่นยำสองเท่าเช่นdouble
ประเภทคือค่า 64 บิตโดยที่:
- 1 บิตหมายถึงเครื่องหมาย (บวกหรือลบ)
- 11 บิตสำหรับเลขชี้กำลัง
- 52 บิตสำหรับตัวเลขนัยสำคัญ (ส่วนที่เป็นเศษส่วนเป็นไบนารี)
ชิ้นส่วนเหล่านี้รวมกันเพื่อผลิต double
แสดงค่า
(ที่มา: Wikipedia: ความแม่นยำสองเท่า )
สำหรับคำอธิบายโดยละเอียดเกี่ยวกับวิธีการจัดการค่าจุดลอยตัวใน Java โปรดดูที่ หัวข้อ 4.2.3: ประเภทจุดลอยตัวรูปแบบและค่าของข้อกำหนดภาษา Java
byte
, char
, int
, long
ประเภทที่มีจุดคงที่ตัวเลขซึ่งเป็น representions ที่แน่นอนของตัวเลข ซึ่งแตกต่างจากหมายเลขจุดคงที่จำนวนจุดลอยตัวจะบางครั้ง (ปลอดภัยที่จะถือว่า "เกือบตลอดเวลา") ไม่สามารถคืนค่าตัวเลขที่แน่นอนได้ นี่คือเหตุผลว่าทำไมคุณจบลงด้วยการ11.399999999999
ที่เป็นผลมาจากการ5.6 + 5.8
ที่เป็นผลมาจากการ
เมื่อต้องการค่าที่แน่นอนเช่น 1.5 หรือ 150.1005 คุณจะต้องใช้หนึ่งในประเภทจุดคงที่ซึ่งจะสามารถแสดงตัวเลขได้อย่างแน่นอน
ดังที่มีการกล่าวถึงหลายครั้งแล้ว Java มี BigDecimal
คลาสที่จะจัดการกับตัวเลขที่มีขนาดใหญ่มากและตัวเลขที่น้อยมาก
จาก Java API Reference สำหรับBigDecimal
คลาส:
ตัวเลขทศนิยมที่ไม่เปลี่ยนรูปและไม่แน่นอนและไม่แน่นอน BigDecimal ประกอบด้วยค่า unscaled จำนวนเต็มความแม่นยำโดยพลการและสเกลจำนวนเต็ม 32 บิต ถ้าเป็นศูนย์หรือบวกค่าสเกลคือจำนวนหลักทางด้านขวาของจุดทศนิยม หากลบค่าที่ไม่ปรับสัดส่วนของจำนวนนั้นจะถูกคูณด้วยสิบถึงกำลังของการปฏิเสธของสเกล ค่าของตัวเลขที่แสดงโดย BigDecimal จึงเป็น (unscaledValue × 10 ^ -scale)
มีคำถามมากมายเกี่ยวกับ Stack Overflow ที่เกี่ยวข้องกับเรื่องของจำนวนจุดลอยตัวและความแม่นยำ นี่คือรายการคำถามที่เกี่ยวข้องที่อาจเป็นที่สนใจ:
ถ้าคุณอยากที่จะได้รับลงไปที่รายละเอียด nitty ทรายลอยหมายเลขจุดจะดูที่อะไรทุกนักวิทยาศาสตร์คอมพิวเตอร์ควรรู้เกี่ยวกับจุดลอยเลขคณิต