2016-06-11 7 views
0

Mein Problem ist wirklich einfach (albern, vielleicht). Ich brauche eine lange Zufallszahl mit der C-Sprache so einfach wie möglich. Ich recherchierte im Internet und konnte nichts finden, was mir helfen könnte. Das einzige, was ich finden konnte, war, dass die Funktion rand() nicht mit Zahlen größer als 32.767 umgehen kann.Lange Zufallszahlen in C

Hier ist ein Teil meines Codes, und die lange Zahl sollte zwischen 0 und 1.000.000:

#include <stdio.h> 
#include <time.h> 
#include <conio.h> 

#define MAX 999999 

void main() 
{ 
    int i; 

    printf("\n Just a test with random numbers."); 

    printf("\n ------------------------------------\n\n"); 

    srand(time(NULL)); 

    for(i = 0; i < 50; i++) 
    { 
     printf(" %li\n", rand() % MAX+1); 
    } 

    printf("\n ====================================\n"); 
    getch(); 
} 

Antwort

-1

Eine schlecht, aber Arbeitslösung das Ergebnis der rand() mit MAX/RAND_MAX (I sein würde, sich zu vermehren glaube, es gab eine Konstante dafür, wenn nicht, 32767).

Ich denke immer noch, dass es da draußen einen Rand für die größeren Zahlen geben sollte.

EDIT: Müssen die Division auf Float (oder Doppel) tippen, dann wieder zu lang.

3

Sie können größere Nummern mit OR erstellen: zusammen mehrere Aufrufe von rand().

#include <stdbool.h> 
#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 

#define LIMIT (1000000) 

static uint16_t highest_bit(uint64_t v) { 
    uint16_t out = 0; 
    while (v > 0) { 
     v >>= 1; 
     ++out; 
    } 
    return out; 
} 

uint32_t myrand() { 
    static bool init = 0; 
    static uint16_t n; 
    static uint16_t shift; 
    if (!init) { 
     uint16_t randbits = highest_bit(RAND_MAX + (uint64_t)1L); 
     uint16_t outbits = highest_bit(LIMIT); 
     n = (outbits + randbits - 1)/randbits; 
     shift = randbits; 
     init = 1; 
    } 
    uint32_t out = 0; 
    for (uint16_t i=0; i<n; ++i) { 
     out |= rand() << (i*shift); 
    } 
    return out % LIMIT; 
} 

Es sollte beachtet werden, dass dieses Verfahren vorgespannt sein wird (das heißt alle Zahlen die gleiche Wahrscheinlichkeit nicht haben), und es ist definitiv nicht kryptografisch sicheren. Wenn Sie das wollen, sollten Sie rand() überhaupt nicht verwenden.

Hier ist eine kleine Hauptfunktion zu testen, dass alle Zahlen mindestens möglich zu bekommen ist:

int main() { 
    bool* seen = calloc(LIMIT, sizeof(bool)); 
    if (!seen) { 
     fprintf(stderr, "failed to malloc 'seen' array\n"); 
     return 1; 
    } 
    uint32_t nseen = 0; 
    uint32_t ntries = 0; 
    // this could take a long time -- you can use Ctrl-C to abort a command-line program 
    while (nseen < LIMIT) { 
     if ((ntries & 0xffff) == 0) { 
      printf("after %u tries, we've seen %u different numbers.\n", ntries, nseen); 
     } 
     ++ntries; 
     uint32_t r = myrand(); 
     if (!seen[r]) { 
      seen[r] = true; 
      ++nseen; 
     } 
    } 
    printf("Found them all after %u tries!\n", ntries); 
    return 0; 
} 
1

Ich gehe davon aus, dass Sie eine Zufallszahl im Bereich wollen [0, 1000000 [, die in einem Bereich liegt, Länge von 10 .

Es ist genau das gleiche wie die Auswahl von zwei Zufallszahlen im Bereich [0, 1000 [, einer für die höherwertigen (dezimalen) Ziffern, einer für die niedrigwertigen. Aber es ist viel einfacher, in diesem Bereich zu arbeiten ...

Wenn Sie eine korrekte Zufallsgenerierung wünschen, sollten Sie sich um die Wahrscheinlichkeit jeder möglichen Zahl kümmern und versuchen, sie so gleich wie möglich zu halten. Sie müssen also zuerst die größte Potenz von 1000 unterhalb von RAND_MAX suchen, alle Zahlen, die größer als diese sind, ablehnen und den Modul 1000 von jedem gehaltenen Wert nehmen.

// Find the max number to keep 
int period = 1000 
unsigned int max = period; 
while (max < (unsigned long) RAND_MAX) { 
    unsigned long t = max * period; 
    if (t < max) break; // test for a possible overflow 
    max = t; 
} 

Sie können dann

for(;;) { 
    unsigned long randnum = rand(); 
    if (randnum < max) { 
     randnum %= period; 
     break; 
    } 
} 

verwenden Und wenn Sie zwei Zufallszahl in Bereich [0, 1000 [, sagen n1 und n2, tun gerade:

n = period * n1 + n2; 

Natürlich gehen Sie davon aus, dass Sie eine korrekte rand Funktion haben. Falls Sie nicht sicher Verwendung random-rand Manpage auf meinem System besagt, verwendet es gleiche algorythm wie random, deshalb nehme ich an ich es sicher verwenden können, aber es sagt auch:

jedoch auf älteren rand() Implementierungen und auf Bei aktuellen Implementierungen auf verschiedenen Systemen sind die Bits niedrigerer Ordnung viel weniger zufällig als die Bits höherer Ordnung.Verwenden Sie diese Funktion nicht in Anwendungen, die portabel sein sollen, wenn eine gute Zufälligkeit erforderlich ist. (Verwenden Sie stattdessen random (3).)

+0

"max" sollte wahrscheinlich auch ein "unsigned long" sein, oder? – Kundor