คำถามติดแท็ก integer-overflow

จำนวนเต็มล้นเกิดขึ้นเมื่อผลลัพธ์ของการดำเนินการมีขนาดใหญ่กว่าค่าสูงสุดที่สามารถแสดงโดยชนิดจำนวนเต็ม

30
ฉันจะตรวจสอบจำนวนเต็มคูณล้นที่ไม่ได้ลงนามอย่างไร
Наэтотвопросестьответына กองมากเกินнарусском : Можнолинаязыках C / C ++ определитьцелочисленноепереполнение? ผมเขียนโปรแกรมใน C ++ เพื่อหาแนวทางแก้ไขปัญหาทั้งหมดของข = คที่, ขและคร่วมกันใช้ตัวเลขทั้งหมด 0-9 ครั้งว่า โปรแกรมวนลูปมากกว่าค่าของaและbและมันรันรูทีนการนับหลักทุกครั้งที่a , bและa bเพื่อตรวจสอบว่าเงื่อนไขหลักเป็นที่พอใจหรือไม่ อย่างไรก็ตามการแก้ปัญหาการปลอมสามารถสร้างขึ้นเมื่อขล้นขีด จำกัด จำนวนเต็ม ฉันสิ้นสุดการตรวจสอบนี้โดยใช้รหัสเช่น: unsigned long b, c, c_test; ... c_test=c*b; // Possible overflow if (c_test/b != c) {/* There has been an overflow*/} else c=c_test; // No …
618 c++  c  integer-overflow 

4
(-2147483648> 0) ผลตอบแทนจริงใน C ++?
-2147483648 เป็นจำนวนเต็มที่น้อยที่สุดสำหรับประเภทจำนวนเต็มด้วย 32 บิต แต่ดูเหมือนว่าจะล้นในif(...)ประโยค: if (-2147483648 > 0) std::cout << "true"; else std::cout << "false"; สิ่งนี้จะพิมพ์ออกมาtrueในการทดสอบของฉัน อย่างไรก็ตามหากเราส่ง -2147483648 ไปเป็นจำนวนเต็มผลลัพธ์จะแตกต่างกัน: if (int(-2147483648) > 0) std::cout << "true"; else std::cout << "false"; falseนี้จะพิมพ์ ฉันสับสน ใครสามารถให้คำอธิบายเกี่ยวกับเรื่องนี้? อัปเดต 02-05-2012: ขอบคุณสำหรับความคิดเห็นของคุณในคอมไพเลอร์ของฉันขนาดของ int คือ 4 ไบต์ ฉันใช้ VC เพื่อทดสอบอย่างง่าย ฉันเปลี่ยนคำอธิบายในคำถามของฉัน นั่นเป็นคำตอบที่ดีมากในโพสต์นี้AndreyTให้คำอธิบายโดยละเอียดเกี่ยวกับวิธีคอมไพเลอร์จะทำงานกับอินพุตเหล่านี้อย่างไรและวิธีการใช้จำนวนเต็มขั้นต่ำนี้ qPCR4virในอีกทางหนึ่งให้ "ความอยากรู้" ที่เกี่ยวข้องและวิธีการแสดงจำนวนเต็ม น่าประทับใจมาก!

12
Java จัดการกับ underflow และ overflows จำนวนเต็มอย่างไรและคุณจะตรวจสอบได้อย่างไร
Java จัดการกับจำนวนเต็มอันเดอร์โฟลว์และโอเวอร์โฟลว์อย่างไร จากนั้นคุณจะตรวจสอบ / ทดสอบว่าสิ่งนี้เกิดขึ้นได้อย่างไร

5
เหตุใดพฤติกรรมที่กำหนดไว้ล้นของจำนวนเต็มล้นที่ไม่ได้ลงนาม แต่ล้นจำนวนเต็มที่ลงนามไม่ได้
จำนวนเต็มมากเกินที่ไม่ได้ลงนามนั้นถูกกำหนดไว้อย่างดีทั้งในมาตรฐาน C และ C ++ ตัวอย่างเช่นมาตรฐาน C99 ( §6.2.5/9) การคำนวณที่เกี่ยวข้องกับตัวถูกดำเนินการที่ไม่ได้ลงนามไม่สามารถเกิน fl ow ได้เนื่องจากผลลัพธ์ที่ไม่สามารถแสดงได้ด้วยประเภทจำนวนเต็มที่ไม่ได้ลงนามผลจะลดลงแบบโมดูโลจำนวนที่มากกว่าหนึ่งค่าที่ใหญ่ที่สุดที่สามารถแสดงด้วยประเภทผลลัพธ์ อย่างไรก็ตามทั้งสองมาตรฐานระบุว่าการโอเวอร์โฟลว์จำนวนเต็มที่ลงนามนั้นเป็นพฤติกรรมที่ไม่ได้กำหนด อีกครั้งจากมาตรฐาน C99 ( §3.4.3/1) ตัวอย่างของพฤติกรรมที่ไม่ได้แก้ไขคือพฤติกรรมของจำนวนเต็มส่วนเกิน มีประวัติศาสตร์หรือ (ดีกว่า!) เหตุผลทางเทคนิคสำหรับความคลาดเคลื่อนนี้หรือไม่?

30
ผลลัพธ์ที่ไม่คาดคิดเมื่อทำงานกับจำนวนเต็มที่มากในภาษาที่ตีความ
ฉันพยายามที่จะได้รับผลรวมของ1 + 2 + ... + 1000000000แต่ฉันได้รับผลตลกใน PHP และNode.js PHP $sum = 0; for($i = 0; $i <= 1000000000 ; $i++) { $sum += $i; } printf("%s", number_format($sum, 0, "", "")); // 500000000067108992 Node.js var sum = 0; for (i = 0; i <= 1000000000; i++) { sum += i …

15
วิธีการหลีกเลี่ยงการล้นใน expr เอบีซีดี
ฉันต้องคำนวณนิพจน์ที่มีลักษณะดังนี้: A*B - C*D, ชนิดของพวกเขาคือ: signed long long int A, B, C, D; แต่ละหมายเลขสามารถมีขนาดใหญ่มาก (ไม่ล้นประเภท) ในขณะที่A*Bอาจทำให้เกิดการล้นในเวลาเดียวกันการแสดงออกA*B - C*Dอาจมีขนาดเล็กมาก ฉันจะคำนวณอย่างถูกต้องได้อย่างไร ตัวอย่างเช่น: MAX * MAX - (MAX - 1) * (MAX + 1) == 1, ที่ไหนMAX = LLONG_MAX - nและ n - จำนวนธรรมชาติบางอย่าง
161 c++  c  integer-overflow 

9
เหตุใด Java จึงคิดว่าผลคูณของตัวเลขทั้งหมดตั้งแต่ 10 ถึง 99 เป็น 0
บล็อกโค้ดต่อไปนี้ให้เอาต์พุตเป็น 0 public class HelloWorld{ public static void main(String []args){ int product = 1; for (int i = 10; i <= 99; i++) { product *= i; } System.out.println(product); } } ใครช่วยอธิบายได้ไหมว่าทำไมถึงเกิดขึ้น

6
(A + B + C) ≠ (A + C + B) และการเรียงลำดับคอมไพเลอร์
การเพิ่มจำนวนเต็ม 32 บิตสองตัวอาจทำให้จำนวนเต็มล้น: uint64_t u64_z = u32_x + u32_y; การโอเวอร์โฟลว์นี้สามารถหลีกเลี่ยงได้หากหนึ่งในจำนวนเต็ม 32 บิตถูกแคสต์หรือเพิ่มเป็นจำนวนเต็ม 64 บิตก่อน uint64_t u64_z = u32_x + u64_a + u32_y; อย่างไรก็ตามหากคอมไพเลอร์ตัดสินใจที่จะจัดลำดับการเพิ่มใหม่: uint64_t u64_z = u32_x + u32_y + u64_a; การล้นจำนวนเต็มอาจยังคงเกิดขึ้น คอมไพเลอร์ได้รับอนุญาตให้ทำการเรียงลำดับใหม่หรือเราสามารถไว้วางใจให้คอมไพเลอร์สังเกตเห็นความไม่สอดคล้องกันของผลลัพธ์และรักษาลำดับนิพจน์ตามที่เป็นอยู่ได้หรือไม่?

14
ฉันจะตรวจสอบได้อย่างไรว่าการคูณสองตัวเลขใน Java จะทำให้ล้นหรือไม่
ฉันต้องการจัดการกรณีพิเศษที่การคูณสองจำนวนเข้าด้วยกันทำให้เกิดการล้น รหัสมีลักษณะดังนี้: int a = 20; long b = 30; // if a or b are big enough, this result will silently overflow long c = a * b; นั่นเป็นเวอร์ชันที่เรียบง่าย ในโปรแกรมจริงaและbมีที่มาจากที่อื่นในรันไทม์ สิ่งที่ฉันต้องการบรรลุมีดังนี้: long c; if (a * b will overflow) { c = Long.MAX_VALUE; } else { c = a …

8
แคสต์ที่ไม่ได้ลงชื่อเพื่อลงนามที่มีประสิทธิภาพหลีกเลี่ยงพฤติกรรมที่กำหนดการนำไปใช้งาน
ฉันต้องการกำหนดฟังก์ชันที่รับunsigned intอาร์กิวเมนต์เป็นและส่งคืนintโมดูโลที่สอดคล้องกัน UINT_MAX + 1 ให้กับอาร์กิวเมนต์ ความพยายามครั้งแรกอาจมีลักษณะดังนี้: int unsigned_to_signed(unsigned n) { return static_cast<int>(n); } แต่อย่างที่นักกฎหมายภาษาใด ๆ ทราบการคัดเลือกจากไม่ได้ลงนามเป็นเซ็นชื่อสำหรับค่าที่มีขนาดใหญ่กว่า INT_MAX นั้นถูกกำหนดให้ใช้งานได้ ฉันต้องการใช้สิ่งนี้ซึ่ง (ก) อาศัยเฉพาะพฤติกรรมที่กำหนดโดยข้อมูลจำเพาะเท่านั้น และ (b) รวบรวมเป็น no-op บนเครื่องที่ทันสมัยและปรับแต่งคอมไพเลอร์ สำหรับเครื่องจักรที่แปลกประหลาด ... หากไม่มีโมดูโลคอนดักเตอร์ int ที่ลงนาม UINT_MAX + 1 ไปยัง int ที่ไม่ได้ลงนามสมมติว่าฉันต้องการยกเว้น ถ้ามีมากกว่าหนึ่ง (ฉันไม่แน่ใจว่าเป็นไปได้) สมมติว่าฉันต้องการอันที่ใหญ่ที่สุด ตกลงครั้งที่สอง: int unsigned_to_signed(unsigned n) { int int_n = static_cast<int>(n); …

12
จุดใดในลูปที่ทำให้จำนวนเต็มล้นกลายเป็นพฤติกรรมที่ไม่ได้กำหนด
นี่เป็นตัวอย่างเพื่ออธิบายคำถามของฉันซึ่งเกี่ยวข้องกับโค้ดที่ซับซ้อนกว่านี้ซึ่งฉันไม่สามารถโพสต์ได้ที่นี่ #include <stdio.h> int main() { int a = 0; for (int i = 0; i < 3; i++) { printf("Hello\n"); a = a + 1000000000; } } โปรแกรมนี้มีพฤติกรรมที่ไม่ได้กำหนดบนแพลตฟอร์มของฉันเพราะaจะล้นในลูปที่ 3 นั่นทำให้โปรแกรมทั้งหมดมีพฤติกรรมที่ไม่ได้กำหนดไว้หรือหลังจากเกิดเหตุการณ์ล้นขึ้นจริงหรือไม่? คอมไพเลอร์สามารถทำงานได้หรือไม่ที่a จะล้นออกมาเพื่อให้สามารถประกาศลูปทั้งหมดโดยไม่ได้กำหนดและไม่ต้องกังวลกับการรัน printfs แม้ว่าทั้งหมดจะเกิดขึ้นก่อนที่จะล้น (ติดแท็ก C และ C ++ แม้ว่าจะแตกต่างกันเพราะฉันสนใจคำตอบสำหรับทั้งสองภาษาหากแตกต่างกัน)

4
มีข้อมูลโค้ด C ที่คำนวณการเพิ่มความปลอดภัยมากเกินไปอย่างมีประสิทธิภาพโดยไม่ใช้คอมไพเลอร์ builtins หรือไม่
นี่คือฟังก์ชั่น C ที่เพิ่มintอีกอันหนึ่งซึ่งล้มเหลวหากเกิดโอเวอร์โฟลว์: int safe_add(int *value, int delta) { if (*value >= 0) { if (delta > INT_MAX - *value) { return -1; } } else { if (delta < INT_MIN - *value) { return -1; } } *value += delta; return 0; } น่าเสียดายที่GCC หรือ Clang นั้นไม่ได้รับการปรับปรุงอย่างดี : safe_add(int*, …

1
ตั้งค่าถ่านเป็น CHAR_MAX รับประกันว่าจะพันไปที่ CHAR_MIN หรือไม่?
รหัสของฉัน: #include <stdio.h> #include <limits.h> int main() { char c = CHAR_MAX; c += 1; printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c); } เอาท์พุท: CHAR_MIN=-128 CHAR_MAX=127 c=-128 () เราจะเห็นว่าเมื่อเราเพิ่มcharชุดตัวแปรก็ล้อมรอบไปCHAR_MAX CHAR_MINพฤติกรรมนี้รับประกันหรือไม่ หรือมันจะเป็นพฤติกรรมที่ไม่ได้กำหนดหรือพฤติกรรมที่ระบุการใช้งาน? มาตรฐาน C99 พูดถึงอะไรเกี่ยวกับเรื่องนี้ [หมายเหตุ: จะเกิดอะไรขึ้นเมื่อให้ค่าที่มากกว่า CHAR_MAX (127) ถึงถ่านหรือC- ทำไมถ่าน c = 129 จะเปลี่ยนเป็น -127 ไม่ตอบคำถามนี้เพราะพวกเขาพูดถึงการกำหนดค่านอกช่วงไม่เพิ่มมูลค่าให้กับค่านอกช่วง]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.