001package squidpony.squidmath; 002 003import squidpony.StringKit; 004 005/** 006 * One of Mark Overton's subcycle generators from <a href="http://www.drdobbs.com/tools/229625477">this article</a>, 007 * specifically a cmr^cmr with two 32-bit states; this is the fastest 32-bit generator that still passes statistical 008 * tests, plus it's optimized for GWT (sometimes). It has a period of just under 2 to the 64, 0xFFF1F6F18B2A1330, which 009 * is roughly 2 to the 63.999691, and allows 2 to the 32 initial seeds. 010 * <br> 011 * This seems to do well in PractRand testing (32 TB passed), but this is not a generator Overton tested. "Chaotic" 012 * generators like this one tend to score well in PractRand, but it isn't clear if they will fail other tests (in 013 * particular, they can't generate all possible long values, and also can't generate 0 or possibly some other ints). As 014 * for desktop/server speed, this is faster than {@link Starfish32RNG} (which is also high-quality) and is also faster 015 * than {@link Lathe32RNG} (which is very fast but has quality issues). However, this is slower than Lathe32RNG when 016 * using GWT and viewing in Firefox; for some reason {@link Starfish32RNG} optimizes well on Firefox and less well on 017 * Chrome, but Mover does ver well in older Chrome (faster than Lathe) and rather poorly on Firefox. It doesn't do 018 * amazingly well in current Chrome versions, however, and Lathe beats it most of the time there. On 64-bit desktop or 019 * server Java, you may want to prefer {@link Mover64RNG}, which is the same algorithm using larger words and constants, 020 * or {@link MiniMover64RNG}, which is even faster but probably has a shorter period than this generator (millions of 021 * seeds have been checked to ensure a minimum period of 2 to the 20 for it, though). While each of the two parts 022 * of a Mover32RNG can have their full period evaluated, making the total period possible to calculate, the same cannot 023 * be said for Mover64RNG or MiniMover64RNG (their maximum periods are high enough for most usage, but the actual totals 024 * are still unknown). 025 * <br> 026 * Its period is 0xFFF1F6F18B2A1330 for the largest cycle, which it always initializes into if {@link #setState(int)} is 027 * used. setState() only allows 2 to the 32 starting states, but less than 2 to the 64 states are in the largest cycle, 028 * so using a long or two ints to set the state seems ill-advised. The generator has two similar parts, each updated 029 * without needing to read from the other part. Each is a 32-bit CMR generator, which multiplies a state by a constant, 030 * rotates by another constant, and stores that as the next state. The particular constants used here were found by 031 * randomly picking 16-bit odd numbers as multipliers, checking the period for every non-zero rotation, and reporting 032 * the multiplier and rotation amount when a period was found that was greater than 0xFF000000. Better multipliers are 033 * almost guaranteed to exist, but finding them would be a challenge. 034 * <br> 035 * This is a RandomnessSource but not a StatefulRandomness because it needs to take care and avoid seeds that would put 036 * it in a short-period subcycle. It uses two generators with different cycle lengths, and skips at most 65536 times 037 * into each generator's cycle independently when seeding. It uses constants to store 128 known midpoints for each 038 * generator, which ensures it calculates an advance for each generator at most 511 times. 039 * <br> 040 * The name comes from M. Overton, who discovered this category of subcycle generators, and also how this generator can 041 * really move when it comes to speed. 042 * <br> 043 * Created by Tommy Ettinger on 8/6/2018. 044 * @author Mark Overton 045 * @author Tommy Ettinger 046 */ 047public final class Mover32RNG implements RandomnessSource { 048 private int stateA, stateB; 049 public Mover32RNG() 050 { 051 setState((int)((Math.random() * 2.0 - 1.0) * 0x80000000)); 052 } 053 public Mover32RNG(final int state) 054 { 055 setState(state); 056 } 057 058 /** 059 * Not advised for external use; prefer {@link #Mover32RNG(int)} because it guarantees a good subcycle. This 060 * constructor allows all subcycles to be produced, including ones with a shorter period. 061 * @param stateA 062 * @param stateB 063 */ 064 public Mover32RNG(final int stateA, final int stateB) 065 { 066 this.stateA = stateA == 0 ? 1 : stateA; 067 this.stateB = stateB == 0 ? 1 : stateB; 068 } 069 070 private static final int[] startingA = { 071 0x00000001, 0xCB2DA1A7, 0x215A5ADF, 0x2688266B, 0xEA31ECEE, 0x3F02F6A8, 0xB0833422, 0xC791ACA6, 072 0x976236C8, 0xF57961C0, 0x16EBE830, 0xCCCC2F10, 0x165D9801, 0x15E02FEA, 0xA302CC65, 0xAF68AE37, 073 0x4997CCA3, 0xF331F604, 0xF1DE5DA7, 0x07F21BA7, 0xD1752EC7, 0x308B16F2, 0x1B92D899, 0xF1A38AC8, 074 0x58F317B2, 0x1CC8EC79, 0x62588F4B, 0x975BF8FE, 0xE589C2D0, 0xB087C03D, 0x600F5DD0, 0xA32BD629, 075 0x3B52D26D, 0x0C7C18FD, 0xEB037A63, 0xE6F8BC93, 0x2CD250CF, 0x84327882, 0xA708FC6E, 0x5873EF12, 076 0x72FD78CF, 0xFFE73771, 0x18817285, 0x8EB3BC50, 0xE68597E0, 0xDF719E77, 0x35FE32C8, 0xF60532A1, 077 0xE93A1484, 0x697DF36B, 0xDFD41306, 0x37E0FADD, 0x6883EB39, 0xAF9CF955, 0xE11EB329, 0xDA951CC2, 078 0x325ECD67, 0x1DD8AC79, 0x7632669F, 0x0949BCB0, 0x965B0557, 0xB72DC0BC, 0x84448A7C, 0x6AC9B9CF, 079 0x92B7742A, 0xCFB27744, 0xFF154B26, 0xFD11E5F7, 0x5B6DE8D4, 0x59727211, 0x0A36FF7F, 0x56657899, 080 0xF9848758, 0x59415D9E, 0xE70E6901, 0x90858D00, 0x10B73995, 0x324FC7AD, 0xC62F801D, 0x4BBDA0E8, 081 0x70C8FDD5, 0xCC4376F1, 0x489AD7B7, 0xF4FB2500, 0x2279E051, 0x7840BF9E, 0x876AABF9, 0xF374F7BD, 082 0x6074B429, 0xC2EE6430, 0x238172DA, 0xFE3D050E, 0x5EF2F6B4, 0xF6359946, 0x127AAD89, 0xECA6FA56, 083 0x678B27CE, 0xDCD03A3C, 0xA45371BB, 0x5F2F422C, 0xE26B613C, 0x70DD9AF4, 0x1B0787BB, 0x0B8D2553, 084 0x3A430C3F, 0xAFF29AE2, 0x9DFAEB51, 0x1DE0F40E, 0x0467D74A, 0x85949411, 0xF8BC0358, 0x558BA744, 085 0x41A5B43A, 0x6B7E1C89, 0x9BF095BD, 0x5E2473CC, 0x4DFBF45B, 0xFB3510DC, 0xB7EC5786, 0xA99D6129, 086 0x120988F6, 0x796A7DE7, 0x9DEFD945, 0x0D2B25CE, 0xB7C1107E, 0x72E29D75, 0x85E01D79, 0x69AB992F, 087 }, startingB = { 088 0x00000001, 0xAB7EE445, 0x6FB35C9C, 0x459AB7A2, 0xEA61D065, 0x306F5E5F, 0xCE50A64A, 0x6D76B642, 089 0x11F3C6D4, 0xB3FF1D66, 0x657E6790, 0x4C62472D, 0xBEABAB16, 0xFD455176, 0xDCB98EDB, 0x1FC27360, 090 0x80C1241C, 0xC0C5BCC0, 0x6A67518B, 0xF2D69A39, 0xFA7D6C16, 0xE906A517, 0x899FFA7B, 0x2E42A99D, 091 0xBAF5B6E8, 0x3BBDC45A, 0x2497A707, 0xEA2DB138, 0x7D4ABF97, 0x552F5D4E, 0x15FE4BBD, 0xBC51DF5A, 092 0x465BDC95, 0x736A018F, 0x8A72CB63, 0x103119BE, 0x40403117, 0xA295957B, 0xCDDA9C19, 0xF0551CC6, 093 0x77CBAB76, 0xA054FD6A, 0x8974C93F, 0x8E314DC1, 0x42BC030E, 0x7F090540, 0x177998EA, 0x20457F09, 094 0xC13609D7, 0xA2683753, 0xE9F84638, 0x1BE07B83, 0x5DB36480, 0x39AE5B3A, 0xE044E164, 0x6E6B6191, 095 0x6036E5C8, 0x00703FE1, 0x53935ED8, 0x6B4443F5, 0x8FB91605, 0x146478C9, 0x2D0429BB, 0x86E8F88A, 096 0xD8DFFDB7, 0x77223F7D, 0x2B065674, 0xD80D2DD6, 0x0DFE5CEB, 0x44A495A5, 0x758EF0A9, 0x5FB55BA5, 097 0x8935A9B1, 0x84189069, 0xAA2194BC, 0x5FB95103, 0x6B60B887, 0xC63A769E, 0xA74BE357, 0x9F71B1F8, 098 0x3320B09E, 0xD369B3FC, 0xBCDB4B4E, 0xDC4DBCC9, 0x01F67CD2, 0xB3F6AA2B, 0x082CA2B3, 0xA54F168F, 099 0x0A9F82C9, 0x77DC3F93, 0x18D32D96, 0x1FC3FCE5, 0x97542B7A, 0x88CA9F81, 0x75370CE4, 0x8C2749C3, 100 0x94B63AE4, 0xC55E3BB7, 0x176BA775, 0x8C2BFEFC, 0x8C457557, 0xD8BFFD54, 0xB3D322DC, 0x072D766C, 101 0x40912BF4, 0x99CA7F36, 0xBC78BE45, 0x22F95B6B, 0xB37B05C9, 0x23493DB3, 0xCFBDC9C3, 0xB0379084, 102 0x2A2BFA20, 0x9A9DA93D, 0xCDE62486, 0x079CF8E6, 0x5B45CF64, 0xA19945A8, 0x196C1AA8, 0x9B19C771, 103 0x702CC28B, 0xFF4C5B02, 0x2FDD78D2, 0x71FFBD4E, 0xDF4C60A4, 0x143FAB0B, 0xAD9C8EB0, 0x6F35837D, 104 }; 105 106 public final void setState(final int s) { 107 stateA = startingA[s >>> 9 & 0x7F]; 108 for (int i = s & 0x1FF; i > 0; i--) { 109 stateA *= 0x89A7; 110 stateA = (stateA << 13 | stateA >>> 19); 111 } 112 stateB = startingB[s >>> 25]; 113 for (int i = s >>> 16 & 0x1FF; i > 0; i--) { 114 stateB *= 0xBCFD; 115 stateB = (stateB << 17 | stateB >>> 15); 116 } 117 } 118 119 public final int nextInt() 120 { 121 int y = stateA * 0x89A7; 122 stateA = (y = (y << 13 | y >>> 19)); 123 final int x = stateB * 0xBCFD; 124 return (y ^ (stateB = (x << 17 | x >>> 15))); 125 } 126 @Override 127 public final int next(final int bits) 128 { 129 int y = stateA * 0x89A7; 130 stateA = (y = (y << 13 | y >>> 19)); 131 final int x = stateB * 0xBCFD; 132 return (y ^ (stateB = (x << 17 | x >>> 15))) >>> (32 - bits); 133 } 134 @Override 135 public final long nextLong() 136 { 137 int y = stateA * 0x89A7; 138 y = (y << 13 | y >>> 19); 139 int x = stateB * 0xBCFD; 140 final long t = (y ^ (x = (x << 17 | x >>> 15))) & 0xFFFFFFFFL; 141 y *= 0x89A7; 142 stateA = (y = (y << 13 | y >>> 19)); 143 x *= 0xBCFD; 144 return t << 32 | ((y ^ (stateB = (x << 17 | x >>> 15))) & 0xFFFFFFFFL); 145 } 146 147 /** 148 * Produces a copy of this Mover32RNG that, if next() and/or nextLong() are called on this object and the 149 * copy, both will generate the same sequence of random numbers from the point copy() was called. This just need to 150 * copy the state so it isn't shared, usually, and produce a new value with the same exact state. 151 * 152 * @return a copy of this Mover32RNG 153 */ 154 @Override 155 public Mover32RNG copy() { 156 return new Mover32RNG(stateA, stateB); 157 } 158 159 /** 160 * Gets the "A" part of the state; if this generator was set with {@link #Mover32RNG()}, {@link #Mover32RNG(int)}, 161 * or {@link #setState(int)}, then this will be on the optimal subcycle, otherwise it may not be. 162 * @return the "A" part of the state, an int 163 */ 164 public int getStateA() 165 { 166 return stateA; 167 } 168 169 /** 170 * Gets the "B" part of the state; if this generator was set with {@link #Mover32RNG()}, {@link #Mover32RNG(int)}, 171 * or {@link #setState(int)}, then this will be on the optimal subcycle, otherwise it may not be. 172 * @return the "B" part of the state, an int 173 */ 174 public int getStateB() 175 { 176 return stateB; 177 } 178 /** 179 * Sets the "A" part of the state to any int, which may put the generator in a low-period subcycle. 180 * Use {@link #setState(int)} to guarantee a good subcycle. 181 * @param stateA any int 182 */ 183 public void setStateA(final int stateA) 184 { 185 this.stateA = stateA; 186 } 187 188 /** 189 * Sets the "B" part of the state to any int, which may put the generator in a low-period subcycle. 190 * Use {@link #setState(int)} to guarantee a good subcycle. 191 * @param stateB any int 192 */ 193 public void setStateB(final int stateB) 194 { 195 this.stateB = stateB; 196 } 197 198 @Override 199 public String toString() { 200 return "Mover32RNG with stateA 0x" + StringKit.hex(stateA) + " and stateB 0x" + StringKit.hex(stateB); 201 } 202 203 @Override 204 public boolean equals(Object o) { 205 if (this == o) return true; 206 if (o == null || getClass() != o.getClass()) return false; 207 208 Mover32RNG mover32RNG = (Mover32RNG) o; 209 210 return stateA == mover32RNG.stateA && stateB == mover32RNG.stateB; 211 } 212 213 @Override 214 public int hashCode() { 215 return 31 * stateA + stateB | 0; 216 } 217 218// public static void main(String[] args) 219// { 220// // A 10 0xC010AEB4 221// // B 22 0x195B9108 222// // all 0x04C194F3485D5A68 223// 224// // A 17 0xF7F87D28 225// // B 14 0xF023E25B 226// // all 0xE89BB7902049CD38 227// 228// 229// // A11 B14 0xBBDA9763B6CA318D 230// // A8 B14 0xC109F954C76CB09C 231// // A17 B14 0xE89BB7902049CD38 232//// BigInteger result = BigInteger.valueOf(0xF7F87D28L); 233//// BigInteger tmp = BigInteger.valueOf(0xF023E25BL); 234//// result = tmp.divide(result.gcd(tmp)).multiply(result); 235//// System.out.printf("0x%016X\n", result.longValue()); 236// int stateA = 1, i = 0; 237// for (; ; i++) { 238// if((stateA = Integer.rotateLeft(stateA * 0x9E37, 17)) == 1) 239// { 240// System.out.printf("0x%08X\n", i); 241// break; 242// } 243// } 244// BigInteger result = BigInteger.valueOf(i & 0xFFFFFFFFL); 245// i = 0; 246// for (; ; i++) { 247// if((stateA = Integer.rotateLeft(stateA * 0x4E6D, 14)) == 1) 248// { 249// System.out.printf("0x%08X\n", i); 250// break; 251// } 252// } 253// BigInteger tmp = BigInteger.valueOf(i & 0xFFFFFFFFL); 254// result = tmp.divide(result.gcd(tmp)).multiply(result); 255// System.out.printf("\n0x%016X\n", result.longValue()); 256// 257// } 258 259// public static void main(String[] args) 260// { 261// Mover32RNG m = new Mover32RNG(); 262// System.out.println("int[] startingA = {"); 263// for (int i = 0, ctr = 0; ctr < 128; ctr++, i+= 0x00000200) { 264// m.setState(i); 265// System.out.printf("0x%08X, ", m.stateA); 266// if((ctr & 7) == 7) 267// System.out.println(); 268// } 269// System.out.println("}, startingB = {"); 270// for (int i = 0, ctr = 0; ctr < 128; ctr++, i+= 0x02000000) { 271// m.setState(i); 272// System.out.printf("0x%08X, ", m.stateB); 273// if((ctr & 7) == 7) 274// System.out.println(); 275// } 276// System.out.println("};"); 277// } 278 279///////// BEGIN subcycle finder code and period evaluator 280// public static void main(String[] args) 281// { 282// // multiplying 283// // A refers to 0x9E377 284// // A 10 0xC010AEB4 285// // B refers to 0x64E6D 286// // B 22 0x195B9108 287// // all 0x04C194F3485D5A68 288// 289// // A=Integer.rotateLeft(A*0x9E377, 17) 0xF7F87D28 290// // B=Integer.rotateLeft(A*0x64E6D, 14) 0xF023E25B 291// // all 0xE89BB7902049CD38 292// 293// 294// // A11 B14 0xBBDA9763B6CA318D 295// // A8 B14 0xC109F954C76CB09C 296// // A17 B14 0xE89BB7902049CD38 297//// BigInteger result = BigInteger.valueOf(0xF7F87D28L); 298//// BigInteger tmp = BigInteger.valueOf(0xF023E25BL); 299//// result = tmp.divide(result.gcd(tmp)).multiply(result); 300//// System.out.printf("0x%016X\n", result.longValue()); 301// // 0x9E37 302// // rotation 27: 0xEE06F34D 303// // 0x9E35 304// // rotation 6 : 0xE1183C3A 305// // rotation 19: 0xC4FCFC55 306// // 0x9E3B 307// // rotation 25: 0xE69313ED 308// // 0xDE4D 309// // rotation 3 : 0xF6C16607 310// // rotation 23: 0xD23AD58D 311// // rotation 29: 0xC56DC41F 312// // 0x1337 313// // rotation 7: 0xF41BD009 314// // rotation 20: 0xF5846878 315// // rotation 25: 0xF38658F9 316// // 0xACED 317// // rotation 28: 0xFC98CC08 318// // rotation 31: 0xFA18CD57 319// // 0xBA55 320// // rotation 19: 0xFB059E43 321// // 0xC6D5 322// // rotation 05: 0xFFD78FD4 323// // 0x5995 324// // rotation 28: 0xFF4AB87D 325// // rotation 02: 0xFF2AA5D5 326// // 0xA3A9 327// // rotation 09: 0xFF6B3AF7 328// // 0xB9EF 329// // rotation 23: 0xFFAEB037 330// // 0x3D29 331// // rotation 04: 0xFF6B92C5 332// // 0x5FAB 333// // rotation 09: 0xFF7E3277 // seems to be very composite 334// // 0xCB7F 335// // rotation 01: 0xFF7F28FE 336// // 0x89A7 337// // rotation 13: 0xFFFDBF50 // wow! note that this is a multiple of 16 338// // 0xBCFD 339// // rotation 17: 0xFFF43787 // second-highest yet, also an odd number 340// // 0xA01B 341// // rotation 28: 0xFFEDA0B5 342// // 0xC2B9 343// // rotation 16: 0xFFEA9001 344// 345// 346// // adding 347// // 0x9E3779B9 348// // rotation 2 : 0xFFCC8933 349// // rotation 7 : 0xF715CEDF 350// // rotation 25: 0xF715CEDF 351// // rotation 30: 0xFFCC8933 352// // 0x6C8E9CF5 353// // rotation 6 : 0xF721971A 354// // 0x41C64E6D 355// // rotation 13: 0xFA312DBF 356// // rotation 19: 0xFA312DBF 357// // rotation 1 : 0xF945B8A7 358// // rotation 31: 0xF945B8A7 359// // 0xC3564E95 360// // rotation 1 : 0xFA69E895 also 31 361// // rotation 5 : 0xF2BF5E23 also 27 362// // 0x76BAF5E3 363// // rotation 14: 0xF4DDFC5A also 18 364// // 0xA67943A3 365// // rotation 11: 0xF1044048 also 21 366// // 0x6C96FEE7 367// // rotation 2 : 0xF4098F0D 368// // 0xA3014337 369// // rotation 15: 0xF3700ABF also 17 370// // 0x9E3759B9 371// // rotation 1 : 0xFB6547A2 also 31 372// // 0x6C8E9CF7 373// // rotation 7 : 0xFF151D74 also 25 374// // rotation 13: 0xFD468E2B also 19 375// // rotation 6 : 0xF145A7EB also 26 376// // 0xB531A935 377// // rotation 13: 0xFF9E2F67 also 19 378// // 0xC0EF50EB 379// // rotation 07: 0xFFF8A98D also 25 380// // 0x518DC14F 381// // rotation 09: 0xFFABD755 also 23 // probably not prime 382// // 0xA5F152BF 383// // rotation 07: 0xFFB234B2 also 27 384// // 0x8092D909 385// // rotation 10: 0xFFA82F7C also 22 386// // 0x73E2CCAB 387// // rotation 09: 0xFF9DE8B1 also 23 388// // stateB = rotate32(stateB + 0xB531A935, 13) 389// // stateC = rotate32(stateC + 0xC0EF50EB, 7) 390// 391// // subtracting, rotating, and bitwise NOT: 392// // 0xC68E9CF3 393// // rotation 13: 0xFEF97E17, also 19 394// // 0xC68E9CB7 395// // rotation 12: 0xFE3D7A2E 396// 397// // left xorshift 398// // 5 399// // rotation 15: 0xFFF7E000 400// // 13 401// // rotation 17: 0xFFFD8000 402// 403// // minus left shift, then xor 404// // state - (state << 12) ^ 0xC68E9CB7, rotation 21: 0xFFD299CB 405// // add xor 406// // state + 0xC68E9CB7 ^ 0xDFF4ECB9, rotation 30: 0xFFDAEDF7 407// // state + 0xC68E9CB7 ^ 0xB5402ED7, rotation 01: 0xFFE73631 408// // state + 0xC68E9CB7 ^ 0xB2B386E5, rotation 24: 0xFFE29F5D 409// // sub xor 410// // state - 0x9E3779B9 ^ 0xE541440F, rotation 22: 0xFFFC9E3E 411// 412// 413// // best power of two: 414// // can get 63.999691 with: (period is 0xFFF1F6F18B2A1330) 415// // multiplying A by 0x89A7 and rotating left by 13 416// // multiplying B by 0xBCFD and rotating left by 17 417// // can get 63.998159 with: (period is 0xFFAC703E2B6B1A30) 418// // multiplying A by 0x89A7 and rotating left by 13 419// // multiplying B by 0xB9EF and rotating left by 23 420// // can get 63.998 with: 421// // adding 0x9E3779B9 for A and rotating left by 2 422// // xorshifting B left by 5 (B ^ B << 5) and rotating left by 15 423// // can get 63.99 with: 424// // adding 0x9E3779B9 for A and rotating left by 2 425// // adding 0x6C8E9CF7 for B and rotating left by 7 426// // can get 63.98 with: 427// // adding 0x9E3779B9 for A and rotating left by 2 428// // multiplying by 0xACED, NOTing, and rotating left by 28 for B 429// // 0xFF6B3AF7L 0xFFAEB037L 0xFFD78FD4L 430// 431// // 0xFF42E24AF92DCD8C, 63.995831 432// //BigInteger result = BigInteger.valueOf(0xFF6B3AF7L), tmp = BigInteger.valueOf(0xFFD78FD4L); 433// 434// BigInteger result = BigInteger.valueOf(0xFFFDBF50L), tmp = BigInteger.valueOf(0xFFF43787L); 435// result = tmp.divide(result.gcd(tmp)).multiply(result); 436// tmp = BigInteger.valueOf(0xFFEDA0B5L); 437// result = tmp.divide(result.gcd(tmp)).multiply(result); 438// System.out.printf("\n0x%s, %2.6f\n", result.toString(16).toUpperCase(), Math.log(result.doubleValue()) / Math.log(2)); 439//// tmp = BigInteger.valueOf(0xFFABD755L); 440//// result = tmp.divide(result.gcd(tmp)).multiply(result); 441//// System.out.printf("\n0x%s, %2.6f\n", result.toString(16).toUpperCase(), Math.log(result.doubleValue()) / Math.log(2)); 442// int stateA = 1, i; 443// LinnormRNG lin = new LinnormRNG(); 444// System.out.println(lin.getState()); 445// Random rand = new RNG(lin).asRandom(); 446// for (int c = 1; c <= 200; c++) { 447// //final int r = (ThrustAltRNG.determineInt(20007 + c) & 0xFFFF)|1; 448// final int r = BigInteger.probablePrime(20, rand).intValue(); 449// //System.out.printf("(x ^ x << %d) + 0xC68E9CB7\n", c); 450// System.out.printf("%03d/200, testing r = 0x%08X\n", c, r); 451// for (int j = 1; j < 32; j++) { 452// i = 0; 453// for (; ; i++) { 454// if ((stateA = Integer.rotateLeft(stateA * r, j)) == 1) { 455// if (i >>> 24 == 0xFF) 456// System.out.printf("(state * 0x%08X, rotation %02d: 0x%08X\n", r, j, i); 457// break; 458// } 459// } 460// } 461// } 462// 463//// int stateA = 1, i = 0; 464//// for (; ; i++) { 465//// if((stateA = Integer.rotateLeft(~(stateA * 0x9E37), 7)) == 1) 466//// { 467//// System.out.printf("0x%08X\n", i); 468//// break; 469//// } 470//// } 471//// BigInteger result = BigInteger.valueOf(i & 0xFFFFFFFFL); 472//// i = 0; 473//// for (; ; i++) { 474//// if((stateA = Integer.rotateLeft(~(stateA * 0x4E6D), 17)) == 1) 475//// { 476//// System.out.printf("0x%08X\n", i); 477//// break; 478//// } 479//// } 480//// BigInteger tmp = BigInteger.valueOf(i & 0xFFFFFFFFL); 481//// result = tmp.divide(result.gcd(tmp)).multiply(result); 482//// System.out.printf("\n0x%016X\n", result.longValue()); 483// 484// } 485///////// END subcycle finder code and period evaluator 486 487 488// public static void main(String[] args) 489// { 490// int stateA = 1, stateB = 1; 491// System.out.println("int[] startingA = {"); 492// for (int ctr = 0; ctr < 128; ctr++) { 493// System.out.printf("0x%08X, ", stateA); 494// if((ctr & 7) == 7) 495// System.out.println(); 496// for (int i = 0; i < 512; i++) { 497// stateA *= 0x89A7; 498// stateA = (stateA << 13 | stateA >>> 19); 499// } 500// } 501// System.out.println("}, startingB = {"); 502// for (int ctr = 0; ctr < 128; ctr++) { 503// System.out.printf("0x%08X, ", stateB); 504// if((ctr & 7) == 7) 505// System.out.println(); 506// for (int i = 0; i < 512; i++) { 507// stateB *= 0xBCFD; 508// stateB = (stateB << 17 | stateB >>> 15); 509// } 510// } 511// System.out.println("};"); 512// } 513}