เหตุใดพฤติกรรมที่กำหนดไว้ล้นของจำนวนเต็มล้นที่ไม่ได้ลงนาม แต่ล้นจำนวนเต็มที่ลงนามไม่ได้


209

จำนวนเต็มมากเกินที่ไม่ได้ลงนามนั้นถูกกำหนดไว้อย่างดีทั้งในมาตรฐาน C และ C ++ ตัวอย่างเช่นมาตรฐาน C99 ( §6.2.5/9)

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

อย่างไรก็ตามทั้งสองมาตรฐานระบุว่าการโอเวอร์โฟลว์จำนวนเต็มที่ลงนามนั้นเป็นพฤติกรรมที่ไม่ได้กำหนด อีกครั้งจากมาตรฐาน C99 ( §3.4.3/1)

ตัวอย่างของพฤติกรรมที่ไม่ได้แก้ไขคือพฤติกรรมของจำนวนเต็มส่วนเกิน

มีประวัติศาสตร์หรือ (ดีกว่า!) เหตุผลทางเทคนิคสำหรับความคลาดเคลื่อนนี้หรือไม่?


50
อาจเป็นเพราะมีมากกว่าหนึ่งวิธีในการแสดงจำนวนเต็มที่มีลายเซ็น วิธีใดที่ไม่ได้ระบุไว้ในมาตรฐานอย่างน้อยไม่ได้อยู่ใน C ++
juanchopanza

ลิงค์ที่มีประโยชน์: en.wikipedia.org/wiki/Signed_number_representations
Robᵩ

7
สิ่งที่ juanchopanza พูดนั้นสมเหตุสมผล ตามที่ฉันเข้าใจแล้วมาตรฐาน C ดั้งเดิมในส่วนใหญ่ทำเป็นแนวทางปฏิบัติที่มีอยู่ หากการใช้งานทั้งหมดในเวลานั้นเห็นด้วยกับสิ่งที่ไม่ควรทำ "ล้น" ที่ไม่ได้ลงชื่อนั่นคือเหตุผลที่ดีสำหรับการทำให้เป็นมาตรฐาน พวกเขาไม่เห็นด้วยกับสิ่งที่ล้นที่ลงนามแล้วควรทำอย่างไรจึงไม่ได้มาตรฐาน

2
@DavidElliman wraparound ที่ไม่ได้ลงนามนอกจากนี้สามารถตรวจจับได้ง่าย ( if (a + b < a)) เช่นกัน การโอเวอร์โฟลว์ในการคูณนั้นทำได้ยากสำหรับทั้งประเภทที่ลงชื่อและไม่ได้ลงชื่อ

5
@DavidElliman: มันไม่เพียง แต่เป็นปัญหาว่าคุณสามารถตรวจจับได้ แต่สิ่งที่เป็นผล ในการใช้งานเครื่องหมาย + ค่าMAX_INT+1 == -0ในขณะที่ส่วนประกอบสองอย่างนั้นจะเป็นINT_MIN
David Rodríguez - dribeas

คำตอบ:


163

เหตุผลทางประวัติศาสตร์คือส่วนใหญ่การใช้งาน C (คอมไพเลอร์) เพียงใช้สิ่งที่พฤติกรรมล้นที่ง่ายที่สุดที่จะใช้กับการเป็นตัวแทนจำนวนเต็มที่มันใช้ การใช้งาน C มักจะใช้การแทนแบบเดียวกับที่ใช้โดยซีพียู - ดังนั้นพฤติกรรมล้นตามมาจากการแทนค่าจำนวนเต็มที่ใช้โดยซีพียู

ในทางปฏิบัติมันเป็นเพียงการรับรองสำหรับค่าลงนามที่อาจแตกต่างกันไปตามการดำเนินการ: ส่วนประกอบหนึ่งของส่วนประกอบสองของ - ขนาดสัญญาณ สำหรับประเภทที่ไม่ได้ลงนามไม่มีเหตุผลสำหรับมาตรฐานที่จะอนุญาตให้มีการเปลี่ยนแปลงเนื่องจากมีเพียงการแสดงไบนารีที่ชัดเจนเพียงรายการเดียวเท่านั้น (มาตรฐานเท่านั้นที่อนุญาตให้แสดงไบนารีได้)

คำพูดที่เกี่ยวข้อง:

C99 6.2.6.1:3 :

ค่าที่เก็บไว้ในบิตฟิลด์ที่ไม่ได้ลงนามและวัตถุประเภทถ่านที่ไม่ได้ลงนามจะแสดงโดยใช้สัญกรณ์ไบนารีบริสุทธิ์

C99 6.2.6.2:2 :

ถ้าบิตเครื่องหมายเป็นหนึ่งค่าจะต้องแก้ไขด้วยวิธีใดวิธีหนึ่งต่อไปนี้:

- ค่าที่สอดคล้องกับบิต 0 เป็นโมฆะ ( เครื่องหมายและขนาด );

- เครื่องหมายบิตมีค่า - (2 N ) ( ส่วนเติมเต็มสอง )

- เครื่องหมายบิตมีค่า - (2 N - 1) ( ส่วนประกอบหนึ่งตัว )


ทุกวันนี้โปรเซสเซอร์ทั้งหมดใช้การเป็นตัวแทนของทั้งสองส่วน แต่การโอเวอร์โหลดทางคณิตศาสตร์ที่ลงนามยังคงไม่ได้กำหนด ดูตัวอย่างโพสต์บล็อกนี้โดย Ian Lance Taylor หรือการร้องเรียนนี้โดย Agner Fog และคำตอบสำหรับรายงานข้อผิดพลาดของเขา


6
แม้ว่าข้อความสำคัญที่นี่คือว่าไม่มีสถาปัตยกรรมใดในโลกสมัยใหม่ที่ใช้สิ่งอื่นใดนอกเหนือไปจากเลขคณิตที่สมบูรณ์ของ 2 มาตรฐานทางภาษานั้นยังอนุญาตให้นำไปปฏิบัติได้เช่น PDP-1 เป็นสิ่งประดิษฐ์ทางประวัติศาสตร์อันบริสุทธิ์
Andy Ross

9
@AndyRoss แต่ยังคงมีระบบ (คอมไพเลอร์ OS +, เป็นที่ยอมรับในประวัติศาสตร์เก่า) พร้อมด้วยส่วนประกอบที่สมบูรณ์และรีลีสใหม่ในปี 2013 ตัวอย่าง: OS 2200
ouah

3
@Andy Ross คุณจะพิจารณาว่า "ไม่มีสถาปัตยกรรม ... ใช้สิ่งอื่นนอกเหนือจากส่วนเสริม 2 ... " วันนี้มีขอบเขตของ DSP และตัวประมวลผลแบบฝังอยู่ด้วยหรือไม่?
chux - Reinstate Monica

11
@AndyRoss: ในขณะที่มี "ไม่" สถาปัตยกรรมที่ใช้สิ่งอื่นที่ไม่ใช่ส่วนเสริม 2s (สำหรับคำจำกัดความของ "ไม่") บางอย่างมีสถาปัตยกรรม DSP ที่ใช้เลขคณิตอิ่มตัวสำหรับจำนวนเต็มลงนาม
สตีเฟ่นแคนนอน

10
เลขคณิตแบบอิ่มตัวที่ลงนามนั้นสอดคล้องกับมาตรฐานอย่างแน่นอน แน่นอนว่าต้องใช้คำแนะนำการห่อสำหรับคณิตศาสตร์ที่ไม่ได้ลงนาม แต่คอมไพเลอร์มีข้อมูลเสมอที่จะรู้ว่าการคำนวณทางคณิตศาสตร์ที่ไม่ได้ลงชื่อหรือที่ลงนามนั้นกำลังทำอยู่หรือไม่ดังนั้นจึงสามารถเลือกคำแนะนำได้อย่างเหมาะสม
คาเฟ่

15

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

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


23
คอมไพเลอร์ไม่ต้องการให้คุณพึ่งพาพวกเขาในการทำสิ่งที่ถูกต้องและส่วนใหญ่จะแสดงให้คุณทันทีที่คุณคอมไพล์int f(int x) { return x+1>x; }ด้วยการปรับให้เหมาะสม GCC และ ICC return 1;ทำกับตัวเลือกเริ่มต้นเพิ่มประสิทธิภาพด้านบนเพื่อ
Pascal Cuoq

1
สำหรับโปรแกรมตัวอย่างที่ให้ผลลัพธ์ที่แตกต่างเมื่อต้องเผชิญกับภาวะintน้ำล้นขึ้นอยู่กับระดับการปรับให้เหมาะสมดูideone.com/cki8nMฉันคิดว่านี่แสดงให้เห็นว่าคำตอบของคุณให้คำแนะนำที่ไม่ดี
แมกนัส Hoff

ฉันได้แก้ไขส่วนนั้นเล็กน้อย
Mats Petersson

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

1
ค่าลบต้องมีอยู่และ "ทำงาน" เพื่อให้คอมไพเลอร์ทำงานอย่างถูกต้องแน่นอนว่าเป็นไปได้ทั้งหมดที่จะหลีกเลี่ยงค่าที่ลงชื่อในโปรเซสเซอร์และใช้ค่าที่ไม่ได้ลงนามไม่ว่าจะเป็นส่วนประกอบที่สมบูรณ์หรือสององค์ประกอบใดก็ตาม ความรู้สึกขึ้นอยู่กับสิ่งที่ชุดคำสั่งคือ โดยทั่วไปแล้วการทำเช่นนี้จะช้ากว่าการสนับสนุนฮาร์ดแวร์ แต่ก็ไม่แตกต่างจากโปรเซสเซอร์ที่ไม่รองรับ floating point ในฮาร์ดแวร์หรือที่คล้ายกัน - เพิ่มรหัสพิเศษจำนวนมาก
Mats Petersson

10

ก่อนอื่นโปรดทราบว่า C11 3.4.3 เช่นตัวอย่างและบันทึกย่อเท้าทั้งหมดไม่ใช่ข้อความเชิงบรรทัดฐานดังนั้นจึงไม่เกี่ยวข้องกับการอ้างอิง!

ข้อความที่เกี่ยวข้องที่ระบุว่าการล้นของจำนวนเต็มและลอยนั้นเป็นพฤติกรรมที่ไม่ได้กำหนดคือ:

C11 6.5 / 5

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

คำชี้แจงเกี่ยวกับพฤติกรรมของประเภทจำนวนเต็มไม่ได้ลงนามโดยเฉพาะสามารถพบได้ที่นี่:

C11 6.2.5 / 9

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

สิ่งนี้ทำให้ชนิดจำนวนเต็มที่ไม่ได้ลงนามเป็นกรณีพิเศษ

นอกจากนี้โปรดทราบว่ามีข้อยกเว้นหากประเภทใดก็ตามถูกแปลงเป็นประเภทที่มีลายเซ็นและค่าเก่าจะไม่สามารถแสดงได้อีกต่อไป พฤติกรรมนั้นเป็นเพียงการนำไปปฏิบัติ - กำหนดแม้ว่าสัญญาณอาจถูกยกขึ้น

C11 6.3.1.3

6.3.1.3 จำนวนเต็มที่ลงชื่อและไม่ได้ลงชื่อ

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

มิฉะนั้นถ้าประเภทใหม่ไม่ได้ลงชื่อค่าจะถูกแปลงโดยการเพิ่มหรือลบซ้ำ ๆ มากกว่าค่าสูงสุดที่สามารถแสดงในรูปแบบใหม่จนกว่าค่านั้นจะอยู่ในช่วงของประเภทใหม่

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


6

นอกเหนือจากปัญหาอื่น ๆ ที่กล่าวถึงการห่อคณิตศาสตร์ที่ไม่ได้ลงนามทำให้ประเภทจำนวนเต็มไม่ได้ลงนามทำตัวเป็นกลุ่มพีชคณิตนามธรรม (หมายถึงว่าเหนือสิ่งอื่นใดสำหรับคู่ของค่าใด ๆXและYจะมีค่าอื่น ๆZเช่นนั้นX+Zหากเหมาะสม เท่ากับYและY-Zจะถ้าหล่ออย่างถูกต้องเท่ากันX) หากค่าที่ไม่ได้ลงนามเป็นเพียงประเภทสถานที่จัดเก็บและไม่ใช่ประเภทนิพจน์ระดับกลาง (เช่นหากไม่มีประเภทเทียบเท่าจำนวนเต็มที่ใหญ่ที่สุดและการดำเนินการทางคณิตศาสตร์สำหรับประเภทที่ไม่ได้ลงนามนั้นจะถูกแปลงเป็นประเภทที่เซ็นชื่อขนาดใหญ่กว่า จะไม่จำเป็นต้องมีพฤติกรรมการห่อที่กำหนดไว้มาก แต่เป็นการยากที่จะทำการคำนวณในรูปแบบที่ไม่มีอินเวิร์สการบวก

สิ่งนี้จะช่วยในสถานการณ์ที่พฤติกรรมการล้อมรอบมีประโยชน์จริง - ตัวอย่างเช่นกับหมายเลขลำดับ TCP หรืออัลกอริทึมบางอย่างเช่นการคำนวณแฮช นอกจากนี้ยังอาจช่วยในสถานการณ์ที่จำเป็นในการตรวจจับการล้นเนื่องจากการคำนวณและการตรวจสอบว่าพวกเขาล้นมักจะง่ายกว่าการตรวจสอบล่วงหน้าว่าพวกเขาจะล้นโดยเฉพาะอย่างยิ่งถ้าการคำนวณที่เกี่ยวข้องกับชนิดจำนวนเต็มที่มีขนาดใหญ่ที่สุด


ฉันไม่ค่อยทำตาม - ทำไมจึงช่วยให้มีการผกผันเพิ่มเติมได้ ฉันไม่สามารถจริงๆคิดว่าสถานการณ์ใด ๆ ที่พฤติกรรมล้นเป็นประโยชน์จริง ...
sleske

@sleske: การใช้ทศนิยมสำหรับการอ่านของมนุษย์ถ้าเครื่องวัดพลังงานอ่าน 0003 และการอ่านก่อนหน้าคือ 9995 นั่นหมายความว่ามีการใช้พลังงาน -9992 หน่วยหรือใช้พลังงาน 0008 หน่วย? มีผลตอบแทน 0003-9995 0008 ทำให้ง่ายต่อการคำนวณผลลัพธ์หลัง ถ้าให้มันถึง -9992 จะทำให้มันอึดอัดใจเล็กน้อย ไม่สามารถทำเช่นนั้นได้ แต่จะทำให้จำเป็นต้องเปรียบเทียบ 0003 ถึง 9995 สังเกตว่ามันน้อยลงทำการลบย้อนกลับลบผลลัพธ์ที่ได้จาก 9999 และเพิ่ม 1
supercat

@sleske: มันมีประโยชน์มากสำหรับทั้งมนุษย์และผู้รวบรวมเพื่อให้สามารถใช้กฎการเชื่อมโยงการแจกแจงและการสลับสับเปลี่ยนของเลขคณิตเพื่อเขียนการแสดงออกและทำให้มันง่ายขึ้น; ตัวอย่างเช่นหากนิพจน์a+b-cนั้นคำนวณภายในลูป แต่bและcมีความคงที่ภายในห่วงว่ามันอาจจะเป็นประโยชน์ที่จะย้ายคำนวณ(b-c)นอกห่วง แต่การทำที่จะต้องเหนือสิ่งอื่น ๆ ที่(b-c)ให้ผลคุ้มค่าซึ่งเมื่อเพิ่มให้a, จะให้ผลa+b-cซึ่งในทางกลับกันต้องcมีสิ่งที่ตรงกันข้าม
supercat

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

1
... เช่นนั้น(a+b)-cเท่ากับa+(b-c)หรือไม่คุ้มค่าเลขคณิตของเป็นแทนได้ภายในชนิดทดแทนจะถูกต้องโดยไม่คำนึงถึงช่วงที่เป็นไปได้ของค่าสำหรับb-c (b-c)
supercat

1

อาจเป็นอีกเหตุผลหนึ่งว่าทำไมกำหนดเลขคณิตไม่ได้ลงนามเป็นเพราะตัวเลขที่ไม่ได้ลงนามในรูปแบบจำนวนเต็มโมดูโล 2 ^ n โดยที่ n คือความกว้างของจำนวนที่ไม่ได้ลงนาม ตัวเลขที่ไม่ได้ลงนามเป็นเพียงจำนวนเต็มแทนด้วยเลขฐานสองแทนตัวเลขทศนิยม การปฏิบัติงานมาตรฐานในระบบมอดุลัสเป็นที่เข้าใจกันดี

คำกล่าวอ้างของ OP อ้างถึงข้อเท็จจริงนี้ แต่ยังเน้นถึงความจริงที่ว่ามีเพียงวิธีเดียวที่ไม่คลุมเครือและเป็นตรรกะในการแสดงจำนวนเต็มที่ไม่ได้ลงนามในไบนารี ในทางตรงกันข้ามตัวเลขที่มีการลงนามมักใช้แทนส่วนเติมเต็มสองส่วน แต่ตัวเลือกอื่น ๆ มีความเป็นไปได้ดังที่อธิบายไว้ในมาตรฐาน (ส่วน 6.2.6.2)

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


สำหรับโครงสร้างที่จะเป็นเขตข้อมูลทุกองค์ประกอบของโครงสร้างอื่น ๆ นอกเหนือจากตัวตนเสริมจะต้องมีการผกผันทวีคูณ โครงสร้างของจำนวนเต็ม mod ที่สอดคล้องกัน N จะเป็นเขตข้อมูลเฉพาะเมื่อ N เป็นหนึ่งหรือเฉพาะ [เขตข้อมูล degnerate เมื่อ N == 1] มีอะไรที่คุณรู้สึกว่าฉันไม่ได้รับคำตอบ?
supercat

คุณพูดถูก ฉันสับสนโดยโมเดอเรเตอร์พลังพิเศษ แก้ไขคำตอบเดิมแล้ว
YTH

เสริมความสับสนที่นี่เป็นที่มีเป็นข้อมูลของการสั่งซื้อ 2 ^ n มันเป็นเพียงไม่แหวน isomorphic จำนวนเต็มแบบโมดูโล 2 ^ n
Kevin Ventullo

และ 2 ^ 31-1 เป็น Mersenne Prime (แต่ 2 ^ 63-1 ไม่ใช่นายกรัฐมนตรี) ดังนั้นความคิดดั้งเดิมของฉันจึงถูกทำลาย นอกจากนี้ขนาดจำนวนเต็มก็แตกต่างกันไปในแต่ละวัน ดังนั้นความคิดของฉันคือการปรับปรุงใหม่ที่ดีที่สุด
YTH

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