2013-03-14 3 views
2

편집 : 결과적으로 나는 C 버전의 테스트 코드에 시드 값을 입력했습니다 (이 질문에 붙여 넣은 것과 같지 않음). 그래서 다른 출력을 얻고있었습니다. 모두에게 감사드립니다.간단한 PRNG 알고리즘은 다른 Python/C 출력 - 정수 오버 플로우 차이가 있습니까?

C 프로그램에서 의사 난수를 생성 한 다음 나중에 시드를 파이썬 프로그램에 전달하고 동일한 숫자를 생성해야합니다.

PRNG도 내가 내 머리 고려 뭔가, 그래서 내가 (C에서)를 실현하는 것이를 보았다 :

static unsigned long next = 1; 

/* RAND_MAX assumed to be 32767 */ 
int myrand(void) { 
    next = next * 1103515245 + 12345; 
    return((unsigned)(next/65536) % 32768); 
} 

그리고 순진 포트 :

next = 1 

def myrand(): 
    global next 
    next = next * 1103515245 + 12345 
    return (next/65536) % 32768 

그러나 이러한 두 다른 값을 산출한다. C 구현 오버플로에서 next 것 같아요, 그 이유는 두 가지 기능을 다른 값을 생성합니다. 그러나 파이썬 숫자에는 명시적인 형식이 없으며 오버플로가 없으며 서명도 없습니다. 어떻게하면 파이썬에서이 동작을 복제 할 수 있습니까?

미리 감사드립니다.

+0

'next'라는 이름을 덮어 쓰는 것은 실제로 매우 순진합니다. – wim

+0

필자는 C 언어에서는 십진수 값이 잘리고 파이썬에서는 그렇지 않다라고 생각한다. – Topo

+0

내장 된 파이썬 숫자에는 명시적인 형식이있다. 그들은 더 현대적인 언어이기 때문에 정당하게 행동합니다. 귀하의 질문에 귀하의 C 코드/플랫폼에서 생성 된 처음 몇 숫자를 제공 할 수 있습니까? – wim

답변

2

모든 계산을 모듈로 (%) 2^32 (32 비트 정수 폭이라고 가정)로하면 효과적입니다. 당신은 여기에서 전역 변수를 사용하지 않으

next = 1 
modulo = 2**32 
def myrand(): 
    global next 
    next = ((next * 1103515245) + 12345) % modulo 
    return (next/65536) % 32768 
+2

+1하지만 modulus는 2^32 여야한다고 생각합니다. 결국, 2^32 - 1은 그러한 int에 대해 유효한 값이며, 2^32에서만 랩 어라운드합니다. – FatalError

+1

그리고 파이썬 2^32가 완전히 다른 것 때문에 2 ** 32를해야합니다. – wim

+0

@FatalError 좋은 캐치. – Paul

0
next = 1 
def myrand(): 
    global next 
    next = next * 1103515245 + 12345 
    return (next & 0xFFFFFFFF/65536) % 32768 
+1

SO의 품질 기준을 충족시키기 위해서는이 답변을보다 구체적으로 작성해야합니다. –

2

는 문제가 발전기 기능에 더 적합하다. 그것은 매우 유용한 내장 이름을 그림자 있기 때문에 당신은 확실히 (실제로 내가 아래에 그것을 사용하고 있습니다!) 파이썬에서 변수 이름으로 next을 사용하지 않으

def myrand(seed=1): 
    n = seed 
    while True: 
     n = n * 1103515245 + 12345 
     yield (n // 65536) % 32768 


g = myrand() 
print(next(g)) 
print(next(g)) 
print(next(g)) 

이없이 분명히, python3에 나를 위해 작동 오버플로 처리가 필요하지 않으며 처음 세 입력과 일치합니다. 몇 가지 더 게시하여 어디에/왜 그들이 갈라 지는지 확인할 수 있습니까?

+0

@Topo 그것이 나왔다시피, 나는 광대 다. 그리고 C 버전에서 씨를 타이프했다. 얼마나 창피한가. 레코드의 경우 전역 변수, 덮어 쓰기 등은 간단한 코드 일뿐 실제 코드는 아닙니다. – Salis