Java ไม่ได้ทำอะไรกับจำนวนเต็มล้นสำหรับ int หรือยาวประเภทดั้งเดิมและละเว้นล้นด้วยจำนวนเต็มบวกและลบ
คำตอบนี้ก่อนอธิบายถึงจำนวนเต็มล้นแสดงตัวอย่างว่ามันจะเกิดขึ้นได้อย่างไรแม้จะมีค่ากลางในการประเมินผลการแสดงออกแล้วให้เชื่อมโยงไปยังทรัพยากรที่ให้เทคนิครายละเอียดสำหรับการป้องกันและตรวจสอบล้นจำนวนเต็ม
เลขคณิตและนิพจน์จำนวนเต็มที่ส่งผลให้เกิดโอเวอร์โฟลว์ที่ไม่คาดคิดหรือไม่ถูกตรวจพบเป็นข้อผิดพลาดทั่วไปในการเขียนโปรแกรม ปัญหาจำนวนเต็มล้นที่ไม่คาดคิดหรือไม่ถูกตรวจพบก็เป็นปัญหาด้านความปลอดภัยที่สามารถนำไปใช้ประโยชน์โดยเฉพาะอย่างยิ่งเนื่องจากมีผลต่อวัตถุอาร์เรย์สแต็กและรายการ
ล้นสามารถเกิดขึ้นได้ทั้งในทิศทางบวกหรือลบโดยที่ค่าบวกหรือลบจะเกินกว่าค่าสูงสุดหรือต่ำสุดสำหรับประเภทดั้งเดิมในคำถาม ล้นสามารถเกิดขึ้นได้ในค่ากลางในระหว่างการแสดงออกหรือการประเมินผลการดำเนินงานและมีผลต่อผลลัพธ์ของการแสดงออกหรือการดำเนินงานที่คาดว่าค่าสุดท้ายจะอยู่ในช่วง
บางครั้งการลบมากเกินไปจะเรียกว่าอันเดอร์โฟลว์ผิดพลาด อันเดอร์โฟล์คือสิ่งที่จะเกิดขึ้นเมื่อค่าใกล้ศูนย์มากกว่าค่าที่อนุญาต อันเดอร์โฟล์เกิดขึ้นในเลขคณิตจำนวนเต็มและคาดหวัง อันเดอร์โฟลว์จำนวนเต็มเกิดขึ้นเมื่อการประเมินผลจำนวนเต็มจะอยู่ระหว่าง -1 ถึง 0 หรือ 0 และ 1 สิ่งที่จะเป็นเศษส่วนตัดเป็น 0 นี่เป็นเรื่องปกติและคาดว่าจะมีเลขจำนวนเต็มและไม่ถือว่าเป็นข้อผิดพลาด อย่างไรก็ตามอาจทำให้เกิดข้อผิดพลาดในการโยนรหัสได้ ตัวอย่างหนึ่งคือข้อยกเว้น "ArithmeticException: / by zero" หากผลลัพธ์ของอันเดอร์โฟลว์จำนวนเต็มถูกใช้เป็นตัวหารในนิพจน์
พิจารณารหัสต่อไปนี้:
int bigValue = Integer.MAX_VALUE;
int x = bigValue * 2 / 5;
int y = bigValue / x;
ซึ่งส่งผลให้ x ถูกกำหนดเป็น 0 และการประเมินผลที่ตามมาของ bigValue / x จะส่งข้อยกเว้น "ArithmeticException: / by zero" (เช่นหารด้วยศูนย์) แทนที่จะเป็น y ที่กำหนดค่า 2
ผลลัพธ์ที่คาดหวังสำหรับ x คือ 858,993,458 ซึ่งน้อยกว่าค่า int สูงสุดของ 2,147,483,647 อย่างไรก็ตามผลลัพธ์ระดับกลางจากการประเมินค่า Integer.MAX_Value * 2 จะเป็น 4,294,967,294 ซึ่งเกินค่า int สูงสุดและ -2 ตามการแทนค่าจำนวนเต็ม 2 วินาที การประเมินผลที่ตามมาของ -2 / 5 ประเมินเป็น 0 ซึ่งได้รับมอบหมายให้กับ x
การจัดเรียงนิพจน์ใหม่สำหรับการคำนวณ x ไปยังนิพจน์ที่เมื่อประเมินแล้วหารก่อนการคูณรหัสต่อไปนี้:
int bigValue = Integer.MAX_VALUE;
int x = bigValue / 5 * 2;
int y = bigValue / x;
ผลลัพธ์ใน x ถูกกำหนด 858,993,458 และ y กำลังมอบหมาย 2 ซึ่งคาดว่า
ผลลัพธ์ระดับกลางจาก bigValue / 5 คือ 429,496,729 ซึ่งไม่เกินค่าสูงสุดสำหรับ int การประเมินที่ตามมาของ 429,496,729 * 2 ไม่เกินค่าสูงสุดสำหรับ int และผลลัพธ์ที่คาดหวังได้รับมอบหมายให้เป็น x การประเมินค่า y จะไม่หารด้วยศูนย์ การประเมินผลสำหรับ x และ y ทำงานตามที่คาดไว้
ค่าจำนวนเต็ม Java ถูกเก็บไว้เป็นและทำงานตาม 2s เสริมสมบูรณ์เป็นตัวแทนจำนวนเต็มลงนาม เมื่อค่าผลลัพธ์จะใหญ่กว่าหรือเล็กกว่าค่าจำนวนเต็มสูงสุดหรือต่ำสุดผลลัพธ์ค่าจำนวนเต็มเสริมของ 2 จะแทน ในสถานการณ์ที่ไม่ได้ออกแบบมาอย่างชัดเจนให้ใช้พฤติกรรมการเติม 2s ซึ่งเป็นสถานการณ์ทางคณิตศาสตร์เลขจำนวนเต็มส่วนใหญ่ค่าเสริม 2s ที่เกิดขึ้นจะทำให้ตรรกะการเขียนโปรแกรมหรือข้อผิดพลาดการคำนวณดังแสดงในตัวอย่างด้านบน บทความวิกิพีเดียที่ยอดเยี่ยมอธิบายถึงเลขจำนวนเต็มไบนารีที่ได้รับการยกย่อง 2 ที่นี่: ส่วนประกอบสองอย่าง - Wikipedia
มีเทคนิคในการหลีกเลี่ยงการล้นของจำนวนเต็มโดยไม่ตั้งใจ Techinques อาจถูกจัดประเภทเป็นการใช้การทดสอบตามสภาพก่อนกำหนด, การ upcasting และ BigInteger
การทดสอบตามเงื่อนไขประกอบด้วยการตรวจสอบค่าที่จะเข้าสู่การดำเนินการทางคณิตศาสตร์หรือนิพจน์เพื่อให้แน่ใจว่าการโอเวอร์โฟลว์จะไม่เกิดขึ้นกับค่าเหล่านั้น การเขียนโปรแกรมและการออกแบบจะต้องสร้างการทดสอบเพื่อให้มั่นใจว่าค่าอินพุตจะไม่ทำให้เกิดการโอเวอร์โฟลว์แล้วกำหนดว่าจะทำอย่างไรถ้าค่าอินพุตเกิดขึ้นซึ่งจะทำให้เกิดการโอเวอร์โฟลว์
Upcasting ประกอบด้วยการใช้ชนิดดั้งเดิมที่มีขนาดใหญ่กว่าเพื่อทำการดำเนินการทางคณิตศาสตร์หรือการแสดงออกและจากนั้นกำหนดว่าค่าผลลัพธ์ที่ได้จะเกินค่าสูงสุดหรือต่ำสุดสำหรับจำนวนเต็ม แม้ว่าจะมีการ upcasting แต่ก็ยังมีความเป็นไปได้ที่ค่าหรือค่ากลางบางอย่างในการดำเนินการหรือการแสดงออกจะเกินค่าสูงสุดหรือต่ำสุดสำหรับประเภท upcast และทำให้เกิด overflow ซึ่งจะไม่ถูกตรวจพบและจะทำให้เกิดผลลัพธ์ที่ไม่คาดคิด ผ่านการวิเคราะห์หรือพรีเงื่อนไขอาจเป็นไปได้ที่จะป้องกันไม่ให้ล้นด้วย upcasting เมื่อการป้องกันโดยไม่ต้อง upcasting เป็นไปไม่ได้หรือในทางปฏิบัติ หากจำนวนเต็มในคำถามนั้นมีความยาวประเภทดั้งเดิมแล้วการถ่ายทอดสัญญาณแบบอัพไม่สามารถทำได้ด้วยประเภทดั้งเดิมใน Java
เทคนิค BigInteger ประกอบด้วยการใช้ BigInteger สำหรับการดำเนินการทางคณิตศาสตร์หรือการแสดงออกโดยใช้วิธีการห้องสมุดที่ใช้ BigInteger BigInteger ไม่ล้น มันจะใช้หน่วยความจำที่มีอยู่ทั้งหมดหากจำเป็น โดยปกติแล้ววิธีการทางคณิตศาสตร์ของมันจะมีประสิทธิภาพน้อยกว่าการดำเนินการจำนวนเต็มเล็กน้อยเท่านั้น เป็นไปได้ว่าผลลัพธ์ที่ใช้ BigInteger อาจเกินค่าสูงสุดหรือต่ำสุดสำหรับจำนวนเต็มอย่างไรก็ตามการล้นจะไม่เกิดขึ้นในการคำนวณทางคณิตศาสตร์ที่นำไปสู่ผลลัพธ์ การเขียนโปรแกรมและการออกแบบยังคงต้องพิจารณาว่าจะทำอย่างไรหากผลลัพธ์ BigInteger เกินกว่าค่าสูงสุดหรือต่ำสุดสำหรับประเภทผลลัพธ์ดั้งเดิมที่ต้องการเช่น int หรือ long
โปรแกรม CERT ของ Carnegie Mellon Software Engineering Institute และ Oracle ได้สร้างชุดของมาตรฐานสำหรับการเขียนโปรแกรม Java ที่ปลอดภัย รวมอยู่ในมาตรฐานเป็นเทคนิคในการป้องกันและตรวจสอบจำนวนเต็มล้น มาตรฐานถูกเผยแพร่เป็นแหล่งข้อมูลออนไลน์ที่สามารถเข้าถึงได้อย่างอิสระที่นี่: มาตรฐานการเข้ารหัส CERT Oracle Secure สำหรับ Java
ส่วนมาตรฐานที่อธิบายและมีตัวอย่างที่ใช้งานได้จริงของเทคนิคการเข้ารหัสเพื่อป้องกันหรือตรวจจับการล้นของจำนวนเต็มอยู่ที่นี่: NUM00-J ตรวจจับหรือป้องกันการล้นจำนวนเต็ม
นอกจากนี้ยังมีแบบฟอร์มหนังสือและ PDF ของมาตรฐาน CERT Oracle Secure Coding สำหรับ Java