INT_MIN-1 เป็นอันเดอร์โฟล์หรือโอเวอร์โฟลว์หรือไม่?


10

ฉันดูเหมือนจะจำได้ว่าฉันกำลังอ่านที่

  • underflowหมายความว่าคุณมีขนาดเล็กเกินไปขนาดที่ไม่สามารถนำเสนอได้อีกต่อไปในประเภท
  • overflowหมายความว่าคุณมีขนาดใหญ่เกินไปขนาดที่ไม่สามารถนำเสนอได้อีกต่อไปในประเภท

อย่างไรก็ตามในทางปฏิบัติฉันเข้าใจว่ามีการใช้ข้อกำหนดดังกล่าว

  • underflowหมายความว่าคุณมีค่าน้อยเกินไปที่ไม่สามารถนำเสนอในรูปแบบได้อีกต่อไป
  • overflowหมายความว่าคุณมีขนาดใหญ่เกินไปค่าที่ไม่สามารถนำเสนอได้อีกต่อไปในประเภท

ความหมายที่ถูกต้องที่จะใช้ที่นี่คืออะไร? คำที่กำหนดแตกต่างกันสำหรับประเภทจำนวนเต็มและทศนิยมหรือไม่


2
โดยทั่วไปแล้วคำว่า "อันเดอร์โฟลว์" จะถูกสงวนไว้สำหรับเลขคณิตจุดลอยตัว ด้วยจำนวนเต็มฉันมักจะพูดว่า "ล้น" ไม่ว่าจะเป็นINT_MIN - 1หรือไม่INT_MAX + 1
Charles Salvia

คำตอบ:


15

ฉันไม่สามารถหาแหล่ง "เผด็จการ" ในเรื่องนี้ส่วนใหญ่เป็นเพราะนี่อาจเป็นเรื่องของการประชุมและคำศัพท์มักจะไม่สอดคล้องกันมาก แต่ข้อความที่ตัดตอนมาจาก " Secure Coding ใน C และ C ++ " ของRobert Seacord สรุปความเข้าใจของฉันเกี่ยวกับสถานการณ์:

ล้นจำนวนเต็มเกิดขึ้นเมื่อจำนวนเต็มจะเพิ่มขึ้นเกินกว่าค่าสูงสุดหรือลดลงเกินกว่าค่าต่ำสุด3 ล้นจำนวนเต็มเกี่ยวข้องอย่างใกล้ชิดกับการเป็นตัวแทนพื้นฐาน

เชิงอรรถกล่าวต่อไปว่า:

[3] การลดจำนวนเต็มที่เกินกว่าค่าต่ำสุดของมันมักถูกเรียกว่าunderflowจำนวนเต็มแม้ว่าในทางเทคนิคคำนี้หมายถึงเงื่อนไขจุดลอยตัว

เหตุผลที่เราเรียกมันว่าเป็นจำนวนเต็มล้นเป็นเพราะมีเพียงไม่เพียงพอพื้นที่ที่มีอยู่ในประเภทที่จะแทนค่า ในแง่ที่ว่ามันคล้ายกับหน่วยความจำล้น (ยกเว้นมากกว่าจริงข้ามเขตแดนบัฟเฟอร์ก็มักจะแสดงพฤติกรรมห่อรอบ. *) จากมุมมองนี้ไม่มีความแตกต่างทางความคิดระหว่างและINT_MIN - 1 INT_MAX + 1ในทั้งสองกรณีมีเพียงพื้นที่ไม่เพียงพอในintชนิดของข้อมูลที่จะเป็นตัวแทนทั้งค่า - ดังนั้นสิ่งที่เรามีเป็นล้น

นอกจากนี้ยังอาจมีประโยชน์ที่จะทราบว่าในสถาปัตยกรรมตัวประมวลผล x86 และ x86_64 การลงทะเบียนรวมถึงบิตล้น บิตโอเวอร์โฟลว์ถูกตั้งค่าเมื่อการดำเนินการทางคณิตศาสตร์จำนวนเต็มที่ลงนามล้น นิพจน์INT_MIN - 1จะตั้งค่าบิตส่วนเกิน (ไม่มีบิต "อันเดอร์โฟลว์") ดังนั้นชัดเจนวิศวกรของ AMD และ Intel ใช้คำว่า "โอเวอร์โฟลว์" เพื่ออธิบายผลลัพธ์ของการดำเนินการทางคณิตศาสตร์จำนวนเต็มซึ่งมีบิตมากเกินไปที่จะพอดีกับชนิดข้อมูลโดยไม่คำนึงว่า ค่ามีขนาดใหญ่เกินไปหรือเล็กเกินไป


* ในความเป็นจริงใน C การโอเวอร์โฟลว์จำนวนเต็มที่ลงนามแล้วนั้นเป็นพฤติกรรมที่ไม่ได้กำหนด แต่ในภาษาอื่นเช่น Java การคำนวณทางคณิตศาสตร์ของทั้งสองจะถูกล้อมรอบ


6

มันล้น อันเดอร์โฟลว์ไม่ได้เกิดขึ้นสำหรับค่าจำนวนเต็ม

การโอเวอร์โฟลว์คือเมื่อค่ามีขนาดใหญ่เกินไป (ห่างจากศูนย์มากเกินไป) ที่จะแสดงตามประเภทเฉพาะและอันเดอร์โฟลวันคือเมื่อมีขนาดเล็กเกินไป (ใกล้กับศูนย์มากเกินไป)

เนื่องจากค่าจำนวนเต็มที่ใกล้เคียงกับศูนย์มากที่สุด (1 และ -1) ยังคงสามารถแสดงได้โดยตัวแปรจำนวนเต็มใด ๆ (สมมติว่าเป็นจำนวนเต็มที่มีลายเซ็นที่มีมากกว่าหนึ่งบิต) อันเดอร์โฟล์ไม่สามารถเกิดขึ้นได้

บทความวิกิพีเดีย underflowมีคำอธิบายที่ชัดเจนมาก:

"เทอมเลขคณิตอันเดอร์โฟลว์ (หรือ" โฟล์ดพอยต์อันเดอร์โฟล์ "หรือเพียงแค่" อันเดอร์โฟลว์ ") เป็นเงื่อนไขในโปรแกรมคอมพิวเตอร์ที่สามารถเกิดขึ้นได้เมื่อผลลัพธ์ที่แท้จริงของการดำเนินการจุดลอยตัวมีขนาดเล็กกว่า กว่าค่าที่เล็กที่สุดที่สามารถแทนได้เป็นเลขทศนิยมปกติในประเภทข้อมูลเป้าหมายอันเดอร์โฟลว์สามารถถือได้ว่าเป็นส่วนเกินเชิงลบของเลขชี้กำลังของเลขชี้กำลังลอยตัว "


มันอาจจะมีประโยชน์ที่จะทราบว่าunderflowมักจะใช้เฉพาะในการอ้างถึงเงื่อนไขเฉพาะที่ขนาดของตัวเลขมีขนาดเล็กกว่าของค่าที่ไม่เป็นศูนย์ที่เล็กที่สุดเท่าที่จะเป็นไปได้ แต่ใหญ่กว่าระยะห่างที่เล็กที่สุดเท่าที่เป็นไปได้ คำกรณีที่ตัวเลขตกอยู่ในสิ่งที่บทความวิกิเรียกว่า "underflow gap" ในการใช้งานที่สอดคล้องกับมาตรฐาน IEEE-744 จำนวนที่สามารถแทนค่าได้น้อยที่สุดจะเท่ากับความแตกต่างระหว่างตัวเลขที่น้อยที่สุดดังนั้นอันเดอร์โฟล์ดังกล่าวไม่สามารถเกิดขึ้นได้ แต่นอกโลกพีซีไม่ใช่ทุกระบบที่เป็นไปตามมาตรฐาน IEEE
supercat

2

ในคณิตศาสตร์จำนวนเต็มล้นหมายถึงค่าทั้งใหญ่เกินไปและเล็กเกินไป ในจุดลอยตัวโอเวอร์โฟลหมายถึงเลขชี้กำลังมากเกินไปและอันเดอร์โฟล์หมายถึงเลขชี้กำลังขนาดเล็กเกินไป

ในความเป็นจริงสำหรับประเภทจำนวนเต็มซีพียูไม่มีวิธีที่จะบอกความแตกต่างระหว่างโอเวอร์โฟลว์และอันเดอร์โฟลว์ เพิ่ม 16- บิตต่อไปนี้:

  0x8000 (unsigned 32768, or signed -32767)
+ 0xFFFF (unsigned 65535, or signed -1)
--------
  0x7FFF (32767, the carried '1' is lost)

แน่นอนว่าการตั้งค่าสถานะโอเวอร์โฟลว์ใน CPU จะได้รับการตั้งค่าหลังจากการเพิ่มนี้ การใช้คณิตศาสตร์ลงนามในผลที่ได้คือเกินไปขนาดเล็ก (-32768) การใช้คณิตศาสตร์ที่ไม่ได้ลงชื่อผลมีขนาดใหญ่เกินไป(0x17FFF) เนื่องจากคณิตศาสตร์เสริมของ 2 นั้นเหมือนกันสำหรับประเภทที่ลงชื่อและไม่ได้ลงชื่อดังนั้นoverflowจึงจำเป็นต้องหมายถึงค่าที่มากเกินไปและเล็กเกินไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.