ทำไมแรนด์ () + แรนด์ () สร้างจำนวนลบ?


304

ฉันสังเกตเห็นว่าrand()ฟังก์ชั่นห้องสมุดเมื่อมันถูกเรียกเพียงครั้งเดียวภายในวงมันมักจะสร้างตัวเลขที่เป็นบวก

for (i = 0; i < 100; i++) {
    printf("%d\n", rand());
}

แต่เมื่อฉันเพิ่มสองrand()สายหมายเลขที่สร้างในขณะนี้จะมีจำนวนลบมากกว่า

for (i = 0; i < 100; i++) {
    printf("%d = %d\n", rand(), (rand() + rand()));
}

บางคนสามารถอธิบายได้ว่าทำไมฉันจึงเห็นตัวเลขติดลบในกรณีที่สอง?

PS: srand(time(NULL))ผมเริ่มต้นเมล็ดพันธุ์ก่อนที่จะห่วงเป็น


11
rand()ไม่สามารถลบ ...
twentylemon

293
rand () + rand () สามารถ owerflow
maskacovnik

13
อะไรคือสิ่งที่RAND_MAXสำหรับคอมไพเลอร์ของคุณหรือไม่ stdlib.hคุณมักจะสามารถหาได้ใน (ตลก: ตรวจสอบman 3 randมันมีคำอธิบายหนึ่งบรรทัด "ตัวสร้างตัวเลขสุ่มไม่ดี")
usr2564301

6
abs(rand()+rand())ทำในสิ่งที่โปรแกรมเมอร์ทุกคนมีสติจะทำ ฉันอยากได้ UB ที่เป็นบวกมากกว่าลบ! ;)
Vinicius Kamakura

11
@hexa: นั่นไม่ใช่ sotution สำหรับ UB เนื่องจากมีการเพิ่มขึ้นแล้ว คุณไม่สามารถทำให้ UB กลายเป็นพฤติกรรมที่กำหนดไว้ได้ สติ progrtammer จะหลีกเลี่ยง UB เหมือนตกนรก
ซื่อสัตย์เกินไปสำหรับเว็บไซต์นี้

คำตอบ:


542

rand() ถูกกำหนดให้ส่งคืนจำนวนเต็มระหว่าง 0RAND_MAXและ

rand() + rand()

อาจล้น สิ่งที่คุณสังเกตเห็นน่าจะเป็นผลมาจากพฤติกรรมที่ไม่ได้กำหนดซึ่งเกิดจากการล้นของจำนวนเต็ม


4
@JakubArnold: วิธีการที่เป็นพฤติกรรมการล้นที่ระบุโดยแต่ละภาษาแตกต่างกันอย่างไร เช่นไพ ธ อนไม่มีเลย (หน่วยความจำสูงสุดที่ใช้ได้) เท่าที่ int เพิ่มขึ้น
ซื่อสัตย์เกินไปสำหรับไซต์นี้

2
@Olaf มันขึ้นอยู่กับภาษาที่ตัดสินใจเป็นตัวแทนจำนวนเต็มที่ลงนามแล้ว Javaไม่มีกลไกในการตรวจจับจำนวนเต็มล้น (จนถึง java 8) และกำหนดให้ล้อมรอบและGoใช้การแทนส่วนเติมเต็มของ 2 เท่านั้นและกำหนดว่าถูกต้องตามกฎหมายสำหรับจำนวนเต็มที่ล้นลงนาม เห็นได้ชัดว่า C สนับสนุนส่วนประกอบมากกว่า 2 อย่าง
PP

2
@EvanCarslake ไม่นั่นไม่ใช่พฤติกรรมสากล สิ่งที่คุณพูดคือการเป็นตัวแทนที่สมบูรณ์ของ 2 แต่ภาษา C อนุญาตสำหรับการเป็นตัวแทนอื่น ๆ ด้วย ข้อกำหนดภาษา C กล่าวว่าการลงนามจำนวนเต็มล้นไม่ได้กำหนด ดังนั้นโดยทั่วไปแล้วโปรแกรมไม่ควรขึ้นอยู่กับพฤติกรรมดังกล่าวและต้องเขียนโค้ดอย่างระมัดระวังเพื่อไม่ให้เกิดการล้นของจำนวนเต็ม แต่สิ่งนี้ไม่สามารถใช้ได้กับจำนวนเต็มที่ไม่ได้ลงนามเพราะพวกเขาจะ "ล้อมรอบ" ในลักษณะที่กำหนดไว้อย่างดี (ลดโมดูโล 2) [ดำเนินการต่อ] ...
PP

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

3
@EvanCarslake ย้ายบิตห่างจากคำถามคอมไพเลอร์ซีจะใช้มาตรฐานและสำหรับจำนวนเต็มลงนามพวกเขาสามารถคิดว่าถ้าพวกเขารู้ว่าa + b > a b > 0พวกเขายังสามารถสันนิษฐานได้ว่าถ้ามีคำสั่งจะถูกดำเนินการในภายหลังแล้วค่าปัจจุบันคือลดแล้วa + 5 INT_MAX - 5ดังนั้นแม้ในส่วนเสริมโปรเซสเซอร์ / ล่าม 2 โดยไม่มีโปรแกรมดักจับอาจไม่ทำงานราวกับว่าints เป็นส่วนประกอบ 2 โดยไม่มีกับดัก
Maciej Piechotka

90

ปัญหาคือการเพิ่ม 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 โปรดทราบว่ามาตรฐานไม่ได้ระบุคุณภาพหรือการกระจายแบบสม่ำเสมอของค่าที่คำนวณได้


14
@badmad: แล้วถ้าทั้งสองโทรกลับ 0
ซื่อสัตย์เกินไปสำหรับไซต์นี้

3
@badmad: ฉันแค่สงสัยว่าได้UINT_MAX > INT_MAX != falseรับการรับรองตามมาตรฐาน (ฟังดูเป็นไปได้ แต่ไม่แน่ใจว่าจำเป็นหรือไม่) ถ้าเป็นเช่นนั้นคุณสามารถส่งผลลัพธ์และการเพิ่มเพียงครั้งเดียว (ตามลำดับ!)
ซื่อสัตย์เกินไปสำหรับไซต์นี้

3
มีกำไรในการเพิ่มตัวเลขสุ่มหลายคือเมื่อคุณต้องการการกระจายไม่สม่ำเสมอ: stackoverflow.com/questions/30492259/...
Cœur

6
การหลีกเลี่ยง 0 ง่าย "ในขณะที่ผลคือ 0 ม้วนใหม่"?
Olivier Dulac

2
ไม่เพียง แต่เพิ่มวิธีที่ไม่ดีในการหลีกเลี่ยง 0 เท่านั้น แต่ยังเป็นการกระจายแบบไม่สม่ำเสมออีกด้วย คุณได้รับการแจกแจงเช่นผลลัพธ์ของการทอยลูกเต๋า: 7 คือ 6 เท่าซึ่งน่าจะเป็น 2 หรือ 12
Barmar

36

นี่คือคำตอบของการชี้แจงของคำถามที่เกิดขึ้นในความคิดเห็นที่คำตอบนี้ ,

เหตุผลที่ฉันเพิ่มคือการหลีกเลี่ยง '0' เป็นตัวเลขสุ่มในรหัสของฉัน rand () + rand () เป็นคำตอบที่สกปรกอย่างรวดเร็วซึ่งมาถึงใจฉันทันที

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

การปฏิเสธต่อไปนี้เป็นศูนย์หลีกเลี่ยงพฤติกรรมที่ไม่ได้กำหนดไว้และในกรณีส่วนใหญ่จะเร็วกว่าการโทรสองครั้งไปที่rand():

int rnum;
for (rnum = rand(); rnum == 0; rnum = rand()) {}
// or do rnum = rand(); while (rnum == 0);

9
เกี่ยวกับrand() + 1อะไร
ถามคำถาม

3
@askvictor ที่อาจล้น (แม้ว่าจะไม่น่าเป็นไปได้)
gerrit

3
@gerrit - ขึ้นอยู่กับ MAX_INT และ RAND_MAX
askvictor

3
@gerrit ผมจะประหลาดใจว่าพวกเขาจะไม่เหมือนกัน แต่ผมคิดว่านี่เป็นสถานที่สำหรับ pedants :)
askvictor

10
หาก RAND_MAX == MAX_INT, rand () + 1 จะล้นด้วยความน่าจะเป็นเช่นเดียวกับค่าของ rand () เป็น 0 ซึ่งทำให้โซลูชั่นนี้ไม่มีจุดหมายอย่างสมบูรณ์ หากคุณยินดีที่จะเสี่ยงและไม่สนใจความเป็นไปได้ของการล้นคุณสามารถใช้ rand () ตามที่เป็นอยู่และไม่สนใจความเป็นไปได้ที่จะคืนค่า 0
Emil Jeřábek

3

โดยทั่วไปจะrand()สร้างตัวเลขระหว่าง0และRAND_MAX, และ2 RAND_MAX > INT_MAXในกรณีของคุณ

คุณสามารถมอดุลัสด้วยค่าสูงสุดของชนิดข้อมูลของคุณเพื่อป้องกันการโอเวอร์โฟลว์ หลักสูตรนี้จะขัดขวางการกระจายของตัวเลขสุ่ม แต่randเป็นเพียงวิธีการรับตัวเลขสุ่มอย่างรวดเร็ว

#include <stdio.h>
#include <limits.h>

int main(void)
{
    int i=0;

    for (i=0; i<100; i++)
        printf(" %d : %d \n", rand(), ((rand() % (INT_MAX/2))+(rand() % (INT_MAX/2))));

    for (i=0; i<100; i++)
        printf(" %d : %ld \n", rand(), ((rand() % (LONG_MAX/2))+(rand() % (LONG_MAX/2))));

    return 0;
}

2

อาจเป็นได้ว่าคุณสามารถลองใช้วิธีที่ค่อนข้างยุ่งยากโดยตรวจสอบให้แน่ใจว่าค่าที่ส่งคืนโดยผลรวมของ 2 rand () ไม่เกินค่าของ RAND_MAX แนวทางที่เป็นไปได้คือ sum = rand () / 2 + rand () / 2; สิ่งนี้จะช่วยให้มั่นใจได้ว่าสำหรับคอมไพเลอร์ 16 บิตที่มีค่า RAND_MAX เป็น 32767 แม้ว่าแรนด์ทั้งคู่จะกลับมาเป็น 32767 ก็ตาม (32767/2 = 16383) 16383 + 16383 = 32766 ดังนั้นจะไม่ส่งผลลบ


1
OP ต้องการยกเว้น 0 จากผลลัพธ์ นอกจากนี้ยังไม่ได้ให้การกระจายของค่าสุ่ม
ซื่อสัตย์เกินไปสำหรับไซต์นี้

@Olaf: ไม่มีการรับประกันว่าการโทรติดต่อสองครั้งติดต่อกันrand()จะไม่ทำให้ทั้งคู่เป็นศูนย์ดังนั้นความปรารถนาที่จะหลีกเลี่ยงศูนย์ไม่ใช่เหตุผลที่ดีในการเพิ่มสองค่า ในทางตรงกันข้ามความปรารถนาที่จะมีการแจกแจงแบบไม่สม่ำเสมอจะเป็นเหตุผลที่ดีในการเพิ่มค่าแบบสุ่มสองค่าหากมีความมั่นใจว่าจะไม่เกิดการล้น
supercat

1

เหตุผลที่ฉันเพิ่มคือการหลีกเลี่ยง '0' เป็นตัวเลขสุ่มในรหัสของฉัน rand () + rand () เป็นคำตอบที่สกปรกอย่างรวดเร็วซึ่งมาถึงใจฉันทันที

วิธีแก้ปัญหาอย่างง่าย (โอเคเรียกว่า "แฮ็ค") ซึ่งไม่เคยให้ผลลัพธ์เป็นศูนย์และจะไม่มีวันล้นคือ:

x=(rand()/2)+1    // using divide  -or-
x=(rand()>>1)+1   // using shift which may be faster
                  // compiler optimization may use shift in both cases

สิ่งนี้จะ จำกัด มูลค่าสูงสุดของคุณ แต่ถ้าคุณไม่สนใจสิ่งนั้นสิ่งนี้ก็ใช้ได้ดีสำหรับคุณ


1
Sidenote: ระวังตัวแปรกะที่ลงนามอย่างถูกต้อง มันมีการกำหนดไว้อย่างดีสำหรับค่าที่ไม่ใช่ค่าลบสำหรับเชิงลบเท่านั้น (โชคดีที่rand()ส่งคืนค่าที่ไม่ใช่ค่าลบเสมอ) อย่างไรก็ตามฉันจะปล่อยให้การเพิ่มประสิทธิภาพให้กับคอมไพเลอร์ที่นี่
ซื่อสัตย์เกินไปสำหรับไซต์นี้

@Olaf: โดยทั่วไปการหารที่เซ็นชื่อสองรายการจะมีประสิทธิภาพน้อยกว่าการเปลี่ยนแปลง เว้นแต่จะเป็นนักเขียนคอมไพเลอร์ได้มีการลงทุนความพยายามในการบอกคอมไพเลอร์ที่randจะไม่เป็นลบกะจะมีประสิทธิภาพมากขึ้นกว่าการหารด้วยลงนามจำนวนเต็ม 2 กองโดย2uสามารถทำงานได้ แต่ถ้าxเป็นintอาจส่งผลให้มีคำเตือนเกี่ยวกับการแปลงโดยปริยายจากที่ไม่ได้ลงชื่อ เพื่อลงนาม
supercat

@supercat: โปรดอ่านความคิดเห็นของฉัน car3efully อีกครั้ง คุณควรที่จะรู้ว่าคอมไพเลอร์ที่สมเหตุสมผลจะใช้กะทำอะไร/ 2ต่อไป (ฉันได้เห็นสิ่งนี้แม้กระทั่งบางอย่างเช่น-O0ไม่มีการเพิ่มประสิทธิภาพที่ร้องขออย่างชัดเจน) มันอาจเป็นการเพิ่มประสิทธิภาพเล็กน้อยที่สุดและเป็นที่ยอมรับมากที่สุดของรหัส C จุดคือการหารถูกกำหนดอย่างดีโดยมาตรฐานสำหรับช่วงจำนวนเต็มทั้งหมดไม่เพียง แต่ไม่ใช่ค่าลบ อีกครั้ง: ปล่อยให้ optimsations ไปยังคอมไพเลอร์เขียนรหัสที่ถูกต้องและชัดเจนตั้งแต่แรก สิ่งนี้สำคัญยิ่งกว่าสำหรับผู้เริ่มต้น
ซื่อสัตย์เกินไปสำหรับไซต์นี้

@Olaf: ทุกคอมไพเลอร์ผมได้ทดสอบสร้างรหัสที่มีประสิทธิภาพมากขึ้นเมื่อขยับrand()ขวาโดยหนึ่งหรือหารด้วย2uกว่าเมื่อหารด้วย 2 -O3แม้เมื่อมีการใช้ มีเหตุผลอย่างหนึ่งที่อาจกล่าวได้ว่าการเพิ่มประสิทธิภาพดังกล่าวไม่น่าจะมีความสำคัญ แต่การพูดว่า "ปล่อยให้การเพิ่มประสิทธิภาพเช่นนี้แก่คอมไพเลอร์" จะแปลว่าคอมไพเลอร์จะมีแนวโน้มที่จะดำเนินการ คุณรู้จักคอมไพเลอร์ตัวใดบ้างที่จะเป็นจริง?
supercat

@supercat: คุณควรใช้คอมไพเลอร์ที่ทันสมัยกว่านี้แล้ว gcc เพิ่งสร้างรหัสละเอียดในครั้งสุดท้ายที่ฉันตรวจสอบ Assembler ที่สร้างขึ้น อย่างไรก็ตามเท่าที่ฉัน apprechiate ที่จะมี groopie ฉันไม่ต้องการที่จะ harrassed เพื่อขยายคุณนำเสนอครั้งสุดท้าย โพสต์เหล่านี้มีอายุปีความคิดเห็นของฉันใช้ได้อย่างสมบูรณ์ ขอบคุณ.
ซื่อสัตย์เกินไปสำหรับไซต์นี้

1

เพื่อหลีกเลี่ยง 0 ลองสิ่งนี้:

int rnumb = rand()%(INT_MAX-1)+1;

limits.hคุณจำเป็นต้องมี


4
นั่นจะเพิ่มความน่าจะเป็นเป็นสองเท่าในการได้รับ 1 โดยพื้นฐานแล้วมันจะเหมือนกัน (แต่ช้ากว่าที่เป็นไปได้) ตามเงื่อนไขการบวก 1 ถ้าrand()อัตราผลตอบแทนเป็น 0
ซื่อสัตย์เกินไปสำหรับเว็บไซต์นี้

ใช่คุณพูดถูก Olaf ถ้า rand () = 0 หรือ INT_MAX -1 rnumb จะเป็น 1
Doni

ยิ่งแย่ไปกว่านั้นฉันมาคิดดู จริง ๆ แล้วมันจะเป็นสองเท่าของ propability สำหรับ1และ2(สันนิษฐานทั้งหมดRAND_MAX == INT_MAX) - 1ผมไม่ลืมเกี่ยวกับ
ซื่อสัตย์เกินไปสำหรับไซต์นี้

1
-1ที่นี่ให้บริการไม่มีค่า rand()%INT_MAX+1; จะยังคงสร้างค่าในช่วง [1 ... INT_MAX] เท่านั้น
chux - Reinstate Monica

-2

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

ผู้ที่โพสต์ rand () + 1 กำลังใช้โซลูชันที่ใช้บ่อยที่สุดเพื่อรับประกันว่าพวกเขาจะไม่ได้รับจำนวนลบ แต่วิธีการนั้นไม่ใช่วิธีที่ดีที่สุดเช่นกัน

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

การสละเวลาและความพยายามพิเศษในการตรวจสอบศึกษาและใช้งานฟังก์ชัน rand () อย่างเหมาะสมนั้นคุ้มค่ากับเวลาและความพยายาม แค่สองเซ็นต์ของฉัน ขอให้โชคดีในความพยายามของคุณ ...


2
rand()ไม่ได้ระบุว่าจะใช้เมล็ดพันธุ์ใด มาตรฐานจะระบุให้ใช้เครื่องกำเนิดไฟฟ้าเทียมเทียมไม่ใช่ความสัมพันธ์กับทุกเวลา นอกจากนี้ยังไม่ได้ระบุคุณสมบัติของเครื่องกำเนิดไฟฟ้า ปัญหาที่เกิดขึ้นจริงคือการล้นอย่างชัดเจน โปรดทราบว่าrand()+1จะใช้เพื่อหลีกเลี่ยง0; rand()ไม่ส่งคืนค่าลบ ขออภัย แต่คุณพลาดจุดที่นี่ มันไม่ได้เกี่ยวกับคุณภาพของ PRNG ...
ซื่อสัตย์เกินไปสำหรับเว็บไซต์นี้

... แนวทางปฏิบัติที่ดีภายใต้ GNU / Linux เพื่อการเพาะปลูก/dev/randomและใช้ PRNG ที่ดีหลังจากนั้น (ไม่แน่ใจเกี่ยวกับคุณภาพของrand()glibc) หรือใช้งานอุปกรณ์ต่อไป - เสี่ยงต่อแอปพลิเคชันของคุณเพื่อป้องกันหากเอนโทรปีมีไม่เพียงพอ การพยายามทำให้เอนโทรปีของคุณในแอพพลิเคชั่นนั้นอาจเป็นช่องโหว่ได้ง่ายกว่าเพราะอาจถูกโจมตีได้ง่ายกว่า และตอนนี้มันมาถึงการชุบแข็ง - ไม่ที่นี่
ซื่อสัตย์เกินไปสำหรับเว็บไซต์นี้
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.