ปัญหาคือการเพิ่ม rand()
ส่งกลับค่าของint
ดังนั้นถ้าคุณเพิ่มสองของพวกเขาคุณจะได้รับถึง0...RAND_MAX
RAND_MAX * 2
หากเกินINT_MAX
ผลลัพธ์ของการเพิ่มจะเกินช่วงที่ถูกต้องและint
สามารถเก็บไว้ได้ การล้นของค่าที่เซ็นชื่อนั้นเป็นพฤติกรรมที่ไม่ได้กำหนดและอาจทำให้แป้นพิมพ์ของคุณพูดกับคุณเป็นภาษาต่างประเทศ
เนื่องจากไม่มีกำไรในการเพิ่มผลลัพธ์แบบสุ่มสองรายการความคิดง่ายๆคือการไม่ทำ อีกวิธีหนึ่งคุณสามารถส่งผลลัพธ์แต่ละรายการไปunsigned int
ก่อนการเพิ่มหากสามารถเก็บผลรวมได้ หรือใช้แบบที่มีขนาดใหญ่กว่า โปรดทราบว่าlong
ไม่จำเป็นต้องกว้างเกินกว่าint
จะใช้กับlong long
หากint
มีอย่างน้อย 64 บิต!
สรุป: เพียงหลีกเลี่ยงการเพิ่ม มันไม่ได้ให้ "ความสุ่ม" มากขึ้น หากคุณต้องการบิตมากกว่านี้คุณอาจทำการเชื่อมต่อค่าต่างsum = a + b * (RAND_MAX + 1)
ๆ กัน แต่นั่นอาจต้องใช้ชนิดข้อมูลที่ใหญ่กว่าint
แต่ที่ยังมีแนวโน้มที่ต้องมีขนาดใหญ่กว่าชนิดข้อมูล
เนื่องจากเหตุผลที่ระบุไว้ของคุณคือการหลีกเลี่ยงผลลัพธ์เป็นศูนย์: ไม่สามารถหลีกเลี่ยงได้โดยการเพิ่มผลลัพธ์ของการrand()
โทรสองสายเนื่องจากทั้งสองสามารถเป็นศูนย์ได้ แต่คุณสามารถเพิ่มได้ ถ้านี้ไม่สามารถทำได้ในRAND_MAX == INT_MAX
int
อย่างไรก็ตาม(unsigned int)rand() + 1
จะทำมากมีโอกาสมาก มีแนวโน้ม (ไม่ชัดเจน) เพราะมันต้องการUINT_MAX > INT_MAX
ซึ่งเป็นความจริงสำหรับการใช้งานทั้งหมดที่ฉันรับรู้ (ซึ่งครอบคลุมสถาปัตยกรรมที่ฝังอยู่ค่อนข้างบางส่วน DSP และเดสก์ท็อปมือถือและเซิร์ฟเวอร์แพลตฟอร์มทั้งหมดในช่วง 30 ปีที่ผ่านมา)
คำเตือน:
แม้ว่าโรยแล้วในความคิดเห็นที่นี่โปรดทราบว่าการเพิ่มค่าสองค่าสุ่มไม่ได้รับการกระจายชุด แต่การกระจายสามเหลี่ยมเหมือนกลิ้งลูกเต๋าสอง: จะได้รับ12
(สองลูกเต๋า) 6
ลูกเต๋าทั้งสองต้องแสดง เพราะ11
มีสองรูปแบบที่เป็นไปได้อยู่แล้ว: 6 + 5
หรือ5 + 6
อื่น ๆ
ดังนั้นการเพิ่มก็ไม่ดีเช่นกัน
นอกจากนี้ยังทราบว่าผลที่rand()
จะสร้างที่ไม่เป็นอิสระของแต่ละอื่น ๆ ที่พวกเขาจะสร้างขึ้นโดยเครื่องกำเนิดไฟฟ้าจำนวน pseudorandom โปรดทราบว่ามาตรฐานไม่ได้ระบุคุณภาพหรือการกระจายแบบสม่ำเสมอของค่าที่คำนวณได้
rand()
ไม่สามารถลบ ...