source code

/**
* Robert Sedgewick Algorithms in C++<br>
* Chapter 35 Random Numbers<br>
* Problem4<br>
* フィードバックシフトレジスタで、排他的論理和の代わりに論理和あるいは論理積を用いるとどうなるであろうか?
*/
public class Chapter35RandomNumbersProblem4 {
public static void main(String[] args) {
Chapter35RandomNumbersProblem4 o = new Chapter35RandomNumbersProblem4();
o.runBitXor();
o.runBitOr();
o.runBitAnd();
o.runAnd();
o.runMult();
}

private void runBitXor() {
LinearFeedbackShiftRegister rng = new LinearFeedbackShiftRegister(1, 0, 1, 0);
System.out.format("%4s\n", toBinaryString(rng.a));
for (int i = 0; i < (1 << 4); i++) {
System.out.format("%4s\n", toBinaryString(rng.nextInt()));
}
}

private void runBitOr() {
LinearFeedbackShiftRegister rng = new LinearFeedbackShiftRegister(1, 0, 1, 1);
System.out.format("%4s\n", toBinaryString(rng.a));
for (int i = 0; i < (1 << 4); i++) {
System.out.format("%4s\n", toBinaryString(rng.nextInt()));
}
}

private void runBitAnd() {
LinearFeedbackShiftRegister rng = new LinearFeedbackShiftRegister((1 << 4) - 1 - 1, 0, 1, 2);
System.out.format("%4s\n", toBinaryString(rng.a));
for (int i = 0; i < (1 << 4); i++) {
System.out.format("%4s\n", toBinaryString(rng.nextInt()));
}
}

private void runAnd() {
LinearFeedbackShiftRegister rng = new LinearFeedbackShiftRegister((1 << 4) - 1, 0, 1, 3);
System.out.format("%4s\n", toBinaryString(rng.a));
for (int i = 0; i < (1 << 4); i++) {
System.out.format("%4s\n", toBinaryString(rng.nextInt()));
}
}

private void runMult() {
LinearFeedbackShiftRegister rng = new LinearFeedbackShiftRegister((1 << 4) - 1 - 1, 0, 1, 4);
System.out.format("%4s\n", toBinaryString(rng.a));
for (int i = 0; i < (1 << 4); i++) {
System.out.format("%4s\n", toBinaryString(rng.nextInt()));
}
}

private String toBinaryString(int n) {
String res = "";
for (int i = 0; i < 4; i++) {
res = ((n & (1 << i)) == 0 ? "0" : "1") + res;
}
return res;
}

private class LinearFeedbackShiftRegister {
private int a = (1 << 4) - 1;
private int bit;
private int bit2;
private int operator;

public LinearFeedbackShiftRegister(int seed, int bit, int bit2, int operator) {
a = seed;
this.bit = bit;
this.bit2 = bit2;
this.operator = operator;
}

public int nextInt() {
if (operator == 0) {
a = (a >>> 1) | ((((a >>> bit) & 1) ^ ((a >>> bit2) & 1)) << 3);
} else if (operator == 1) {
a = (a >>> 1) | ((((a >>> bit) & 1) | ((a >>> bit2) & 1)) << 3);
} else if (operator == 2) {
a = (a >>> 1) | ((((a >>> bit) & 1) & ((a >>> bit2) & 1)) << 3);
} else if (operator == 3) {
a = (a >>> 1) | (((((a >>> bit) & 1) + ((a >>> bit2) & 1)) & 1) << 3);
} else if (operator == 4) {
a = (a >>> 1) | (((((a >>> bit) & 1) * ((a >>> bit2) & 1)) & 1) << 3);
}
return a;
}
}
}