All Downloads are FREE. Search and download functionalities are using the official Maven repository.

squidpony.squidmath.Mover64RNG Maven / Gradle / Ivy

Go to download

SquidLib platform-independent logic and utility code. Please refer to https://github.com/SquidPony/SquidLib .

There is a newer version: 3.0.6
Show newest version
package squidpony.squidmath;

import squidpony.StringKit;

/**
 * One of Mark Overton's subcycle generators from this article,
 * specifically a cmr^cmr with two 64-bit states. It is extremely fast, faster than {@link LinnormRNG} and
 * {@link TangleRNG}, but its period is unknown. The period is at the very least 2 to the 38, since each of its
 * sub-generators has been checked up to that period length without running out of period, and the total period of a
 * Mover64RNG should be greater than 2 to the 64 with a very high likelihood. The total period is also very unlikely to
 * be a power of two or even a number close to a power of two; it could be odd or even. The guarantees of Linnorm and
 * Tangle that they are certain to have a period of 2 to the 64 may be worthwhile reasons to use them; they also will be
 * faster when setting the state often. LightRNG is a SkippingRandomness and a StatefulRandomness, but this is neither,
 * so you may want to prefer LightRNG for that reason. This generator is not equidistributed, so it can return some long
 * values more often than others and some not at all; you may want to use a generator with guarantees on distribution if
 * you don't want to see some returned values (or pairs of values) more often than others. {@link Starfish32RNG} is
 * 2-dimensionally equidistributed for ints, so it returns all pairs of ints with equal likelihood, and it may be a good
 * RandomnessSource to use if distribution matters (though you should prefer {@link GWTRNG}, which is implemented using
 * Starfish32RNG, because it is specialized to use a 32-bit generator).
 * 
* This seems to do well in PractRand testing, passing a full 32TB with two ("unusual") anomalies, but this is not one * of the exact generators Overton tested. "Chaotic" generators like this one tend to score well in PractRand, but it * isn't clear if they will fail other tests (in particular, they probably can't generate all possible long values, and * maybe can't generate some ints). This generator is not equidistributed. *
* The generator has two similar parts, each updated without needing to read from the other part. Each is a 64-bit CMR * generator, which multiplies a state by a constant, rotates by another constant, and stores that as the next state. * The multiplier constants used here were chosen arbitrarily, since almost all odd-number multipliers produce a period * for a 64-bit CMR generator that is too long to iterate through and compare. One multiplier is close to the LCG * multiplier used in PractRand (0x41C64E6B); the other is very close to the golden ratio times 2 to the 32 * (0x9E3779B9). Better multipliers are almost guaranteed to exist, but finding them would be a challenge. The rotation * constants, 28 and 37, were chosen so they were sufficiently different and so the sum of their (left or right) * rotation amounts is close to 64, which seems to help quality. Oddly, substituting an addition for one of the two * multiplications slows this generator down reliably, and does nothing to help quality. Even though addition should be * faster, the two near-identical operations performed on two states may be able to be compiled into vector operations * if the compiler is clever enough, but an addition on one state and a multiplication on the other would not make sense * to see SIMD optimization. *
* This is a RandomnessSource but not a StatefulRandomness because it needs to take care and avoid seeds that would put * it in a short-period subcycle. It uses two generators with different cycle lengths, and skips at most 65536 times * into each generator's cycle independently when seeding. It uses constants to store 128 known midpoints for each * generator, which ensures it calculates an advance for each generator at most 511 times. There are 2 to the 32 * possible starting states for this generator when using {@link #setState(int)}, but it is unknown if that method * actually puts the generator in the longest possible cycle, or just a sufficiently long one. *
* The name comes from M. Overton, who discovered this category of subcycle generators, and also how this generator can * really move when it comes to speed. *
* Created by Tommy Ettinger on 9/13/2018. * @author Mark Overton * @author Tommy Ettinger */ public final class Mover64RNG implements RandomnessSource { private long stateA, stateB; public Mover64RNG() { setState((int)((Math.random() * 2.0 - 1.0) * 0x80000000)); } public Mover64RNG(final int state) { setState(state); } /** * Not advised for external use; prefer {@link #Mover64RNG(int)} because it guarantees a good subcycle. This * constructor allows all subcycles to be produced, including ones with a shorter period. * @param stateA * @param stateB */ public Mover64RNG(final long stateA, final long stateB) { this.stateA = stateA == 0L ? 1L : stateA; this.stateB = stateB == 0L ? 1L : stateB; } private static final long[] startingA = { 0x0000000000000001L, 0x770391C6587202CDL, 0x0148D0D6B055DE19L, 0x2CFFDEE4C4C8654FL, 0x3669291DE218F372L, 0x5B744ACB07F3D380L, 0x103F93C86BDF21D0L, 0x9A1D980831BCF2ABL, 0x92D56961736A4B50L, 0x71A9832527530EADL, 0x4C524342889BCFE1L, 0xF39CFA3D37AB4038L, 0xA3E9A70AD8EEF84DL, 0x65C7AFEFFC4DA898L, 0x4D455E304CDC7741L, 0xA6EDACBD6740B1A7L, 0xAA7F8E77C41AF5EBL, 0x96B50AD6E4AA2B18L, 0x77432395B55EDFD9L, 0x2748C2DD4565F1F0L, 0x3CAC2CDB2F8318D0L, 0x7D983C0295175158L, 0xDCFC33F629C3D00FL, 0x1EF0C5B47164F981L, 0x3AB9A3877956251EL, 0xBA230F415A833533L, 0xA489CC2EF532A6BEL, 0xB212F25D09BFC366L, 0xB9014F210A77310DL, 0x8590EF3967A8C6E0L, 0x1011FD4E97B1F81AL, 0x1C57F18A80F4C131L, 0x4AA90F013DB975E3L, 0xB3FAAC7A9374BD99L, 0xA15B9AA709431B2DL, 0xD3201A4C3953FFA2L, 0x0B34634F0B74BAB5L, 0x501389102E6E08EEL, 0xFCAC8A7CFCEB534DL, 0xA6A1A2C7CB5CEE8FL, 0x5F461436431B3D6DL, 0x1F3DE41F1E991A39L, 0x96A5BD1D16EDC265L, 0xAEC3F8C461FA0749L, 0x4445933104846C0BL, 0xAD088B25A4AA0E59L, 0x862FCA81FF8B1BE5L, 0x12E5A795C17DA902L, 0x5CA3CDC494DF2B93L, 0xCF612FCBDD25B41EL, 0xAD0CC4406EC6FCC3L, 0x352336C92FA965EAL, 0x675AB684694EE4A8L, 0x811A5D47EE8B3568L, 0x4937A92A07C372A4L, 0xE1483C680A24BEA4L, 0x1B3E829B910E343CL, 0x0F5F8EF159F931C0L, 0x7F5DDFDA98EFE7EAL, 0xA2FA4A6C79F5C6EFL, 0xEA416C98A2A0945CL, 0x29CC34E89FCC5D02L, 0x157FC5094CCC1795L, 0x27252C1165C6E255L, 0xAB963445C144A9BCL, 0x601530DECC304F69L, 0xC92D8F3257316572L, 0xC348074025724519L, 0x0F8305789523701EL, 0xD288EFE7BDDABF47L, 0xC428DA0AD18149BAL, 0xBA1D19D35E61A11EL, 0x6D81979DC0110FA2L, 0x3C144A6DC2C2982BL, 0x7593425EA77652A8L, 0xBA416F84332EFD0AL, 0x691EAA02B1351B41L, 0xF1B15F5AD69A16BAL, 0x026D58B160B39D4CL, 0x813B48A15DA161E6L, 0xCC92B59765EF4C5FL, 0x46B6C1ED44BF6877L, 0xA679D47C27EA4A03L, 0x393BEF21C904261CL, 0xE40A734EFE039992L, 0xD114E560A35EC443L, 0x85A46B901B80F546L, 0xCC8C80C6AB27F53CL, 0xC9B5FCE7C3EE4A83L, 0x64D4B2A2A91ADC11L, 0x7157576E65940314L, 0x75BF0B0737304143L, 0x4A11300B7F32C8C5L, 0x4B4FB70D7701DD60L, 0xE877F97BEC9E8FACL, 0x151E431374EF9D79L, 0x636214B0856DF427L, 0x088F1774DE7730CFL, 0x9E3B5CD7FF590F81L, 0x4DA157EA25850BC1L, 0xE9C7C31744E062F4L, 0x4767FCAF076B9508L, 0xC5C767D939AC8425L, 0x1ABAF0D4EC698A8FL, 0x5035DC94FA971B81L, 0x718EE38E931713E2L, 0x497DB43133CEF0F2L, 0xF01BE721B0145805L, 0x9D6239853FF80744L, 0x256B893D4DD0689AL, 0x256647CAA07563D6L, 0xCE4087F877A6D24FL, 0x68A0537869364FE2L, 0x32BA732DEC14AE42L, 0x3AAF6CDE0CE8DB48L, 0x552C1D9594CE212AL, 0x8BC1A33AE250B2E9L, 0xC02FCB678B465D00L, 0x496F580658AFD50AL, 0x6D0D982E45AD15A9L, 0xC8E87307F336E8D0L, 0x257E726598418548L, 0xFADF2ED10B13D148L, 0x46FA6CC74F293535L, 0xF03227995C268856L, 0x46087E39622EA4CDL, 0x17EE09D3D2181207L, 0x9C7518A1E5AD4544L, }, startingB = { 0x0000000000000001L, 0x07293E6E09EC6368L, 0x96D969CADB4CD368L, 0x3FF86768F89EAEB3L, 0x2F9FAC39CC8E5CB7L, 0xF0ACF2D0542EE141L, 0x7BF403A079DCD087L, 0xDA68703F5EAB9409L, 0xF887EDE8E8AD388BL, 0xB93108A12DD8DC5CL, 0x98676A8BE90BB48EL, 0x3C66E22B602A7007L, 0x69A56A92BAD39B5BL, 0x58857B966DDF07BCL, 0x3B6890E3EDB96D6EL, 0xF0363B595221C86DL, 0x62EE3C3A7A528614L, 0xB0175247E00B4935L, 0xE70D810777ED42ACL, 0x275CE4F27473631AL, 0xB5DF57C4502967E9L, 0xB8EB0B9EC111C7FEL, 0xC28F3B422CA03689L, 0xD09DD3A8FEAB2DD1L, 0x4E2C713B5A7A0FFCL, 0x9AFC4BE99ED5F1AAL, 0xA89BFD2F6C2E97AEL, 0xF8735B9A6DF5F258L, 0xB2F89E533D9B9897L, 0xD89711EA7777E671L, 0x9658217AF4F448CAL, 0xEE3F474204385F6BL, 0x2B20D085EAB7ECC0L, 0xDF4FBDB5877EC70AL, 0xA27D970C88F1246BL, 0x88D0B336E63ADE23L, 0xC06AF42B0855C181L, 0x00E8B464987358DBL, 0xDA1DF8BA1E45586EL, 0x4C12347AB35D2F03L, 0x752C4942F1095640L, 0x608BD5FC9E04FA0AL, 0xB253E48775CDD5E1L, 0x643E8401460AAA59L, 0xE248C00B3A622F06L, 0xB01AD54DFE588BF2L, 0x1D486285F47A99D0L, 0x4ACE70E9A24E7B42L, 0xE498314246C2E894L, 0x67BB0785AEA67873L, 0xAB50922AD5171ABDL, 0x4BFA6DEE10549DC3L, 0x889BB7C03B745D65L, 0x705D68BC7379AEECL, 0x08BC6282C82C8B72L, 0xB967A84918604EDCL, 0x17F2AE6E78487967L, 0x038874F2D394FB80L, 0x7F7A2F1A581C66D3L, 0x99977A67381F6F7FL, 0x6B62915A4927F8D3L, 0x4DE18BB59A3C182DL, 0x94E508A682455109L, 0x986BE18241462557L, 0x0578DFAE00F8A0D6L, 0x29B22988B2264886L, 0xD552345E6E2A3125L, 0x5DB9E3195164C051L, 0x0E43BA334827D573L, 0x3AFAF8799E87209CL, 0xBC0E249E28B42DE9L, 0x022A07577137E25FL, 0x7DEB553C69DAA1FFL, 0x4A69C3A72EF45E41L, 0xBEBAC3CF3B608398L, 0xEB5771FF214E2487L, 0x9FB5E8C5B36B4CC9L, 0xC09F95341A44B518L, 0x668BEA20B4AE0875L, 0x633E56557743D5CBL, 0x60F91113C85EAAAAL, 0xB7FD377C14A36222L, 0xFCF5360544E39E14L, 0xC8201F79E019A016L, 0x9298BE81EFD5200FL, 0xBEB6A71A91068F67L, 0xB48125BFEFE20180L, 0xC470152566C3E1A0L, 0x46646F5388059BA1L, 0x6B2EFA0363CEB524L, 0xC60186015E2573E1L, 0x514BF9772FA2ACCEL, 0x1C44DACDE62A44EDL, 0x0CC4356D150B5469L, 0xDF21F9DAE98D5C86L, 0xA22573A5D741ACECL, 0x722CB87504029D8AL, 0x5727EA9D310F90F7L, 0x06D1E7DC6CF5C689L, 0x735BAEB75FDD9F85L, 0xEF96C3AF03785BEAL, 0xBE453FC733BEFA00L, 0xE27E2672BFCC1C44L, 0x541C5523E0FBB038L, 0xA04B840944E17E54L, 0x313CA18B6537B063L, 0xC7B93061D18C2FFEL, 0xE1D991D2E4A8CD20L, 0x5BB21B4ED59FAE91L, 0x7DB82C96F57D18C5L, 0x9EEBA39CBD611F6EL, 0x093E9402ABCC23F7L, 0x9A7637252A4475F7L, 0x0C8A522F0B70DB19L, 0x3532D24B07A4D08BL, 0x633C908FA64BB58AL, 0x16A3123AD6B3DD79L, 0x1169BB0D6BD6DEC5L, 0xDABFB787CED62E83L, 0x8F17A15C52A3B9BDL, 0xA2F3FA0F0F5F6FDFL, 0x95DA83EA34697FEFL, 0xFE1541E512CBAC77L, 0xE68287CDEB9302A5L, 0xB928A0223B695207L, 0x3F9D05B291DE5A8AL, 0x5E28B275895A2C79L, 0x8E9BD22FBFD57A6CL, }; public final void setState(final int s) { stateA = startingA[s >>> 9 & 0x7F]; for (int i = s & 0x1FF; i > 0; i--) { stateA *= 0x41C64E6BL; stateA = (stateA << 28 | stateA >>> 36); } stateB = startingB[s >>> 25]; for (int i = s >>> 16 & 0x1FF; i > 0; i--) { stateB *= 0x9E3779B9L; stateB = (stateB << 37 | stateB >>> 27); } } public final int nextInt() { final long a = stateA * 0x41C64E6BL; final long b = stateB * 0x9E3779B9L; return (int)((stateA = (a << 28 | a >>> 36)) ^ (stateB = (b << 37 | b >>> 27))); } @Override public final int next(final int bits) { final long a = stateA * 0x41C64E6BL; final long b = stateB * 0x9E3779B9L; return (int)((stateA = (a << 28 | a >>> 36)) ^ (stateB = (b << 37 | b >>> 27))) >>> (32 - bits); } @Override public final long nextLong() { final long a = stateA * 0x41C64E6BL; final long b = stateB * 0x9E3779B9L; return (stateA = (a << 28 | a >>> 36)) ^ (stateB = (b << 37 | b >>> 27)); } /** * Produces a copy of this Mover64RNG that, if next() and/or nextLong() are called on this object and the * copy, both will generate the same sequence of random numbers from the point copy() was called. This just need to * copy the state so it isn't shared, usually, and produce a new value with the same exact state. * * @return a copy of this Mover64RNG */ @Override public Mover64RNG copy() { return new Mover64RNG(stateA, stateB); } /** * Gets the "A" part of the state; if this generator was set with {@link #Mover64RNG()}, {@link #Mover64RNG(int)}, * or {@link #setState(int)}, then this will be on the optimal subcycle, otherwise it may not be. * @return the "A" part of the state, an int */ public long getStateA() { return stateA; } /** * Gets the "B" part of the state; if this generator was set with {@link #Mover64RNG()}, {@link #Mover64RNG(int)}, * or {@link #setState(int)}, then this will be on the optimal subcycle, otherwise it may not be. * @return the "B" part of the state, an int */ public long getStateB() { return stateB; } /** * Sets the "A" part of the state to any long, which may put the generator in a low-period subcycle. * Use {@link #setState(int)} to guarantee a good subcycle. * @param stateA any int */ public void setStateA(final long stateA) { this.stateA = stateA; } /** * Sets the "B" part of the state to any long, which may put the generator in a low-period subcycle. * Use {@link #setState(int)} to guarantee a good subcycle. * @param stateB any int */ public void setStateB(final long stateB) { this.stateB = stateB; } @Override public String toString() { return "Mover64RNG with stateA 0x" + StringKit.hex(stateA) + " and stateB 0x" + StringKit.hex(stateB); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Mover64RNG mover64RNG = (Mover64RNG) o; return stateA == mover64RNG.stateA && stateB == mover64RNG.stateB; } @Override public int hashCode() { long h = 31L * stateA + stateB; return (int)(h ^ h >>> 32); } // public static void main(String[] args) // { // // A 10 0xC010AEB4 // // B 22 0x195B9108 // // all 0x04C194F3485D5A68 // // // A 17 0xF7F87D28 // // B 14 0xF023E25B // // all 0xE89BB7902049CD38 // // // // A11 B14 0xBBDA9763B6CA318D // // A8 B14 0xC109F954C76CB09C // // A17 B14 0xE89BB7902049CD38 //// BigInteger result = BigInteger.valueOf(0xF7F87D28L); //// BigInteger tmp = BigInteger.valueOf(0xF023E25BL); //// result = tmp.divide(result.gcd(tmp)).multiply(result); //// System.out.printf("0x%016X\n", result.longValue()); // int stateA = 1, i = 0; // for (; ; i++) { // if((stateA = Integer.rotateLeft(stateA * 0x9E37, 17)) == 1) // { // System.out.printf("0x%08X\n", i); // break; // } // } // BigInteger result = BigInteger.valueOf(i & 0xFFFFFFFFL); // i = 0; // for (; ; i++) { // if((stateA = Integer.rotateLeft(stateA * 0x4E6D, 14)) == 1) // { // System.out.printf("0x%08X\n", i); // break; // } // } // BigInteger tmp = BigInteger.valueOf(i & 0xFFFFFFFFL); // result = tmp.divide(result.gcd(tmp)).multiply(result); // System.out.printf("\n0x%016X\n", result.longValue()); // // } // public static void main(String[] args) // { // Mover32RNG m = new Mover32RNG(); // System.out.println("int[] startingA = {"); // for (int i = 0, ctr = 0; ctr < 128; ctr++, i+= 0x00000200) { // m.setState(i); // System.out.printf("0x%08X, ", m.stateA); // if((ctr & 7) == 7) // System.out.println(); // } // System.out.println("}, startingB = {"); // for (int i = 0, ctr = 0; ctr < 128; ctr++, i+= 0x02000000) { // m.setState(i); // System.out.printf("0x%08X, ", m.stateB); // if((ctr & 7) == 7) // System.out.println(); // } // System.out.println("};"); // } ///////// BEGIN subcycle finder code and period evaluator // public static void main(String[] args) // { // // multiplying // // A refers to 0x9E377 // // A 10 0xC010AEB4 // // B refers to 0x64E6D // // B 22 0x195B9108 // // all 0x04C194F3485D5A68 // // // A=Integer.rotateLeft(A*0x9E377, 17) 0xF7F87D28 // // B=Integer.rotateLeft(A*0x64E6D, 14) 0xF023E25B // // all 0xE89BB7902049CD38 // // // // A11 B14 0xBBDA9763B6CA318D // // A8 B14 0xC109F954C76CB09C // // A17 B14 0xE89BB7902049CD38 //// BigInteger result = BigInteger.valueOf(0xF7F87D28L); //// BigInteger tmp = BigInteger.valueOf(0xF023E25BL); //// result = tmp.divide(result.gcd(tmp)).multiply(result); //// System.out.printf("0x%016X\n", result.longValue()); // // 0x9E37 // // rotation 27: 0xEE06F34D // // 0x9E35 // // rotation 6 : 0xE1183C3A // // rotation 19: 0xC4FCFC55 // // 0x9E3B // // rotation 25: 0xE69313ED // // 0xDE4D // // rotation 3 : 0xF6C16607 // // rotation 23: 0xD23AD58D // // rotation 29: 0xC56DC41F // // 0x1337 // // rotation 7: 0xF41BD009 // // rotation 20: 0xF5846878 // // rotation 25: 0xF38658F9 // // 0xACED // // rotation 28: 0xFC98CC08 // // rotation 31: 0xFA18CD57 // // 0xBA55 // // rotation 19: 0xFB059E43 // // 0xC6D5 // // rotation 05: 0xFFD78FD4 // // 0x5995 // // rotation 28: 0xFF4AB87D // // rotation 02: 0xFF2AA5D5 // // 0xA3A9 // // rotation 09: 0xFF6B3AF7 // // 0xB9EF // // rotation 23: 0xFFAEB037 // // 0x3D29 // // rotation 04: 0xFF6B92C5 // // 0x5FAB // // rotation 09: 0xFF7E3277 // seems to be very composite // // 0xCB7F // // rotation 01: 0xFF7F28FE // // 0x89A7 // // rotation 13: 0xFFFDBF50 // wow! note that this is a multiple of 16 // // 0xBCFD // // rotation 17: 0xFFF43787 // second-highest yet, also an odd number // // 0xA01B // // rotation 28: 0xFFEDA0B5 // // 0xC2B9 // // rotation 16: 0xFFEA9001 // // // // adding // // 0x9E3779B9 // // rotation 2 : 0xFFCC8933 // // rotation 7 : 0xF715CEDF // // rotation 25: 0xF715CEDF // // rotation 30: 0xFFCC8933 // // 0x6C8E9CF5 // // rotation 6 : 0xF721971A // // 0x41C64E6D // // rotation 13: 0xFA312DBF // // rotation 19: 0xFA312DBF // // rotation 1 : 0xF945B8A7 // // rotation 31: 0xF945B8A7 // // 0xC3564E95 // // rotation 1 : 0xFA69E895 also 31 // // rotation 5 : 0xF2BF5E23 also 27 // // 0x76BAF5E3 // // rotation 14: 0xF4DDFC5A also 18 // // 0xA67943A3 // // rotation 11: 0xF1044048 also 21 // // 0x6C96FEE7 // // rotation 2 : 0xF4098F0D // // 0xA3014337 // // rotation 15: 0xF3700ABF also 17 // // 0x9E3759B9 // // rotation 1 : 0xFB6547A2 also 31 // // 0x6C8E9CF7 // // rotation 7 : 0xFF151D74 also 25 // // rotation 13: 0xFD468E2B also 19 // // rotation 6 : 0xF145A7EB also 26 // // 0xB531A935 // // rotation 13: 0xFF9E2F67 also 19 // // 0xC0EF50EB // // rotation 07: 0xFFF8A98D also 25 // // 0x518DC14F // // rotation 09: 0xFFABD755 also 23 // probably not prime // // 0xA5F152BF // // rotation 07: 0xFFB234B2 also 27 // // 0x8092D909 // // rotation 10: 0xFFA82F7C also 22 // // 0x73E2CCAB // // rotation 09: 0xFF9DE8B1 also 23 // // stateB = rotate32(stateB + 0xB531A935, 13) // // stateC = rotate32(stateC + 0xC0EF50EB, 7) // // // subtracting, rotating, and bitwise NOT: // // 0xC68E9CF3 // // rotation 13: 0xFEF97E17, also 19 // // 0xC68E9CB7 // // rotation 12: 0xFE3D7A2E // // // left xorshift // // 5 // // rotation 15: 0xFFF7E000 // // 13 // // rotation 17: 0xFFFD8000 // // // minus left shift, then xor // // state - (state << 12) ^ 0xC68E9CB7, rotation 21: 0xFFD299CB // // add xor // // state + 0xC68E9CB7 ^ 0xDFF4ECB9, rotation 30: 0xFFDAEDF7 // // state + 0xC68E9CB7 ^ 0xB5402ED7, rotation 01: 0xFFE73631 // // state + 0xC68E9CB7 ^ 0xB2B386E5, rotation 24: 0xFFE29F5D // // sub xor // // state - 0x9E3779B9 ^ 0xE541440F, rotation 22: 0xFFFC9E3E // // // // best power of two: // // can get 63.999691 with: (period is 0xFFF1F6F18B2A1330) // // multiplying A by 0x89A7 and rotating left by 13 // // multiplying B by 0xBCFD and rotating left by 17 // // can get 63.998159 with: (period is 0xFFAC703E2B6B1A30) // // multiplying A by 0x89A7 and rotating left by 13 // // multiplying B by 0xB9EF and rotating left by 23 // // can get 63.998 with: // // adding 0x9E3779B9 for A and rotating left by 2 // // xorshifting B left by 5 (B ^ B << 5) and rotating left by 15 // // can get 63.99 with: // // adding 0x9E3779B9 for A and rotating left by 2 // // adding 0x6C8E9CF7 for B and rotating left by 7 // // can get 63.98 with: // // adding 0x9E3779B9 for A and rotating left by 2 // // multiplying by 0xACED, NOTing, and rotating left by 28 for B // // 0xFF6B3AF7L 0xFFAEB037L 0xFFD78FD4L // // // 0xFF42E24AF92DCD8C, 63.995831 // //BigInteger result = BigInteger.valueOf(0xFF6B3AF7L), tmp = BigInteger.valueOf(0xFFD78FD4L); // // BigInteger result = BigInteger.valueOf(0xFFFDBF50L), tmp = BigInteger.valueOf(0xFFF43787L); // result = tmp.divide(result.gcd(tmp)).multiply(result); // tmp = BigInteger.valueOf(0xFFEDA0B5L); // result = tmp.divide(result.gcd(tmp)).multiply(result); // System.out.printf("\n0x%s, %2.6f\n", result.toString(16).toUpperCase(), Math.log(result.doubleValue()) / Math.log(2)); //// tmp = BigInteger.valueOf(0xFFABD755L); //// result = tmp.divide(result.gcd(tmp)).multiply(result); //// System.out.printf("\n0x%s, %2.6f\n", result.toString(16).toUpperCase(), Math.log(result.doubleValue()) / Math.log(2)); // int stateA = 1, i; // LinnormRNG lin = new LinnormRNG(); // System.out.println(lin.getState()); // Random rand = new RNG(lin).asRandom(); // for (int c = 1; c <= 200; c++) { // //final int r = (ThrustAlt32RNG.determine(20007 + c) & 0xFFFF)|1; // final int r = BigInteger.probablePrime(20, rand).intValue(); // //System.out.printf("(x ^ x << %d) + 0xC68E9CB7\n", c); // System.out.printf("%03d/200, testing r = 0x%08X\n", c, r); // for (int j = 1; j < 32; j++) { // i = 0; // for (; ; i++) { // if ((stateA = Integer.rotateLeft(stateA * r, j)) == 1) { // if (i >>> 24 == 0xFF) // System.out.printf("(state * 0x%08X, rotation %02d: 0x%08X\n", r, j, i); // break; // } // } // } // } // //// int stateA = 1, i = 0; //// for (; ; i++) { //// if((stateA = Integer.rotateLeft(~(stateA * 0x9E37), 7)) == 1) //// { //// System.out.printf("0x%08X\n", i); //// break; //// } //// } //// BigInteger result = BigInteger.valueOf(i & 0xFFFFFFFFL); //// i = 0; //// for (; ; i++) { //// if((stateA = Integer.rotateLeft(~(stateA * 0x4E6D), 17)) == 1) //// { //// System.out.printf("0x%08X\n", i); //// break; //// } //// } //// BigInteger tmp = BigInteger.valueOf(i & 0xFFFFFFFFL); //// result = tmp.divide(result.gcd(tmp)).multiply(result); //// System.out.printf("\n0x%016X\n", result.longValue()); // // } ///////// END subcycle finder code and period evaluator // public static void main(String[] args) // { // long stateA = 1, stateB = 1; // System.out.println("long[] startingA = {"); // for (int ctr = 0; ctr < 128; ctr++) { // System.out.printf("0x%016XL, ", stateA); // if((ctr & 7) == 7) // System.out.println(); // for (int i = 0; i < 512; i++) { // stateA *= 0x41C64E6BL; // stateA = (stateA << 28 | stateA >>> 36); // } // } // System.out.println("}, startingB = {"); // for (int ctr = 0; ctr < 128; ctr++) { // System.out.printf("0x%016XL, ", stateB); // if((ctr & 7) == 7) // System.out.println(); // for (int i = 0; i < 512; i++) { // stateB *= 0x9E3779B9L; // stateB = (stateB << 37 | stateB >>> 27); // } // } // System.out.println("};"); // } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy