線形合同法であるseedが0からいくつ進めたものかを得る その2

周期2^k, 初項0のLCG数列{x_n}に対して、{x_{2n} / 2}って周期2^(k-1)のLCG数列だよね、というアイディアで再実装してみました。

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

typedef uint32_t u32;

/* x[0] = 0, x[n+1] = (a * x[n] + b) mod 2^k
   で与えられる数列{x[n]}において、x[n] = sを満たすnを求める
   ただし数列の周期は2^kになっていなければならない */
u32 calc_index(u32 a, u32 b, u32 s, u32 k) {
	if (k == 0) {
		return 0;
	} else if ((s & 1) == 0) {
		return calc_index(a * a, (a + 1) * b / 2, s / 2, k - 1) * 2;
	} else {
		return calc_index(a * a, (a + 1) * b / 2, (a * s + b) / 2, k - 1) * 2 - 1;
	}
}

int main(void) {
	u32 A = 0x41c64e6d;
	u32 B = 0x6073;

	printf("%.8x\n", calc_index(A, B, 0, 32));
	printf("%.8x\n", calc_index(A, B, B, 32));
	printf("%.8x\n", calc_index(A, B, A * B + B, 32));
	printf("%.8x\n", calc_index(A, B, A * A * B + A * B + B, 32));
	return 0;
}
筆者: oupo (連絡先: oupo.nejiki@gmail.com)