2016-06-11 4 views
0

내 문제는 정말 간단합니다 (어리석은, 어쩌면). 가능한 한 간단하게 C 언어를 사용하여 긴 난수가 필요합니다. 나는 인터넷을 통해 조사했고 나를 도울 수있는 것을 찾지 못했다. 내가 찾을 수있는 유일한 것은 rand() 함수가 32,767보다 큰 숫자를 처리 할 수 ​​없다는 것입니다. 여기C에서 긴 난수가

내 코드의 일부이며, 0과 1,000,000 긴 수 있어야한다 : 나쁜하지만 일하는 솔루션 MAX/RAND_MAX (I 포함) 랜드 (의 결과를 곱하면하는 것

#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(); 
} 

답변

-1

이것에 대한 상수가 있다고 믿는다. 그렇지 않다면, 32767).

나는 아직도 더 큰 숫자를위한 랜드가 있어야한다고 생각한다.

편집 : 부울을 부동 (또는 이중)으로 유형 변환 한 다음 다시 되돌아 가야합니다.

3

여러 개의 rand() 호출을 OR로 조합하여 더 큰 숫자를 만들 수 있습니다.

#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; 
} 

이 방법 (즉 모든 숫자가 동일한 확률을 가지고 있지 않습니다) 바이어스 될 것을 유의해야하며 확실히 안전한 암호화 아니다. 원하는 경우 rand()을 전혀 사용하지 않아야합니다.

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

난 당신이 범위에 범위 [0에서 임의의 숫자, 1000000 [을한다고 가정 : 여기

모든 숫자는 적어도 를 얻을 수 있음을 테스트하기 위해 약간의 주요 기능입니다 길이는 1이다.

범위 [0, 1000 [하나는 상위 (10 진수) 숫자에 대해 하나는 하위 숫자에 대해 하나씩 두 개의 난수를 선택하는 것과 완전히 동일합니다. 하지만 그 범위에서 일하는 것이 훨씬 쉽습니다 ...

정확한 임의 생성을 원하면 가능한 모든 숫자의 확률을 걱정하고 가능한 한 동일하게 유지해야합니다. 따라서 먼저 RAND_MAX 아래에서 1000의 가장 큰 힘을 검색하고 그보다 큰 숫자를 모두 거부하고 각각의 보관 된 값의 모듈러스 1000을 가져와야합니다.

// 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; 
} 

그런 다음

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

를 사용 할 수 있습니다 범위 [0, 1000 개의 임의의 숫자를 가지고 때, n1n2 말을 바로 수행 물론

n = period * n1 + n2; 

위의 경우 올바른 rand 함수가 있다고 가정합니다. 확실 사용 random 경우 - 내 시스템에 rand 사람 페이지 상태는 내가 안전하게 사용할 수 있습니다 가정 이유 random과 동일한 algorythm을 사용하지만, 그것은 또한 말한다 :

을 그러나, 예전 rand() 구현을하고,에 다른 시스템에서의 현재 구현에서, 하위 비트는 상위 비트보다 훨씬 덜 랜덤하다.좋은 임의성이 필요할 때 이식 가능한 응용 프로그램에서이 기능을 사용하지 마십시오. 대신에 random (3)을 사용하십시오.

+0

'max' 역시 '부호없는 long'이어야합니다. – Kundor