@Override
	public void nextBytes(final byte[] bytes)    
        {
        for (int x=0;x<bytes.length;x++) bytes[x] = (byte)next(8);
        }

    /** For completeness' sake, though it's not in java.util.Random.  
     * @return ? */
    public char nextChar()
        {
        // chars are 16-bit UniCode values
        return (char)(next(16));
        }

    /** For completeness' sake, though it's not in java.util.Random. 
     * @return ? */
    public short nextShort()
        {
        return (short)(next(16));
        }

    /** For completeness' sake, though it's not in java.util.Random.  
     * @return ? */
    public byte nextByte()
        {
        return (byte)(next(8));
        }


    /** A bug fix for all JDK code including 1.2.  nextGaussian can theoretically
        ask for the log of 0 and divide it by 0! See Java bug 
        <a href="http://developer.java.sun.com/developer/bugParade/bugs/4254501.html">
        http://developer.java.sun.com/developer/bugParade/bugs/4254501.html</a>
     * @return ?
    */
    @Override
	synchronized public double nextGaussian() 
        {
        if (__haveNextNextGaussian) 
            {
            __haveNextNextGaussian = false;
            return __nextNextGaussian;
            }
//        else 
//            {
            double v1, v2, s;
            do 
                { 
                v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0
                v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0
                s = v1 * v1 + v2 * v2;
                } while (s >= 1 || s==0 );
            double multiplier = /*Strict*/Math.sqrt(-2 * /*Strict*/Math.log(s)/s);
            __nextNextGaussian = v2 * multiplier;
            __haveNextNextGaussian = true;
            return v1 * multiplier;
            }
//        }
    
    /**
     * Tests the code.
     * @param args 
     */
    public static void main(String args[])
        { 
        int j;

        MersenneTwister r;

        // CORRECTNESS TEST
        // COMPARE WITH http://www.math.keio.ac.jp/matumoto/CODES/MT2002/mt19937ar.out
        
        r = new MersenneTwister(new int[]{0x123, 0x234, 0x345, 0x456});
        System.out.println("Output of MersenneTwister with new (2002/1/26) seeding mechanism");
        for (j=0;j<1000;j++)
            {
            // first, convert the int from signed to "unsigned"
            long l = r.nextInt();
            if (l < 0 ) l += 4294967296L;  // max int value
            String s = String.valueOf(l);
            while(s.length() < 10) s = " " + s;  // buffer
            System.out.print(s + " ");
            if (j%5==4) System.out.println();       
            }

        // SPEED TEST

        final long SEED = 4357;

        int xx; long ms;
        System.out.println("\nTime to test grabbing 100000000 ints");
          
        r = new MersenneTwister(SEED);
        ms = System.currentTimeMillis();
        xx=0;
        for (j = 0; j < 100000000; j++)
            xx += r.nextInt();
        System.out.println("Mersenne Twister: " + (System.currentTimeMillis()-ms) + "          Ignore this: " + xx);

        System.out.println("To compare this with java.util.Random, run this same test on MersenneTwisterFast.");
        System.out.println("The comparison with Random is removed from MersenneTwister because it is a proper");
        System.out.println("subclass of Random and this unfairly makes some of Random's methods un-inlinable,");
        System.out.println("so it would make Random look worse than it is.");

        // TEST TO COMPARE TYPE CONVERSION BETWEEN
        // MersenneTwisterFast.java AND MersenneTwister.java

        
        System.out.println("\nGrab the first 1000 booleans");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextBoolean() + " ");
            if (j%8==7) System.out.println();
            }
        if (!(j%8==7)) System.out.println();
          
        System.out.println("\nGrab 1000 booleans of increasing probability using nextBoolean(double)");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextBoolean(j / 999.0) + " ");
            if (j%8==7) System.out.println();
            }
        if (!(j%8==7)) System.out.println();
          
        System.out.println("\nGrab 1000 booleans of increasing probability using nextBoolean(float)");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextBoolean(j / 999.0f) + " ");
            if (j%8==7) System.out.println();
            }
        if (!(j%8==7)) System.out.println();
          
        byte[] bytes = new byte[1000];
        System.out.println("\nGrab the first 1000 bytes using nextBytes");
        r = new MersenneTwister(SEED);
        r.nextBytes(bytes);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(bytes[j] + " ");
            if (j%16==15) System.out.println();
            }
        if (!(j%16==15)) System.out.println();
        
        byte b;
        System.out.println("\nGrab the first 1000 bytes -- must be same as nextBytes");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print((b = r.nextByte()) + " ");
            if (b!=bytes[j]) System.out.print("BAD ");
            if (j%16==15) System.out.println();
            }
        if (!(j%16==15)) System.out.println();

        System.out.println("\nGrab the first 1000 shorts");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextShort() + " ");
            if (j%8==7) System.out.println();
            }
        if (!(j%8==7)) System.out.println();

        System.out.println("\nGrab the first 1000 ints");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextInt() + " ");
            if (j%4==3) System.out.println();
            }
        if (!(j%4==3)) System.out.println();

        System.out.println("\nGrab the first 1000 ints of different sizes");
        r = new MersenneTwister(SEED);
        int max = 1;
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextInt(max) + " ");
            max *= 2;
            if (max <= 0) max = 1;
            if (j%4==3) System.out.println();
            }
        if (!(j%4==3)) System.out.println();

        System.out.println("\nGrab the first 1000 longs");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextLong() + " ");
            if (j%3==2) System.out.println();
            }
        if (!(j%3==2)) System.out.println();

        System.out.println("\nGrab the first 1000 longs of different sizes");
        r = new MersenneTwister(SEED);
        long max2 = 1;
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextLong(max2) + " ");
            max2 *= 2;
            if (max2 <= 0) max2 = 1;
            if (j%4==3) System.out.println();
            }
        if (!(j%4==3)) System.out.println();
          
        System.out.println("\nGrab the first 1000 floats");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextFloat() + " ");
            if (j%4==3) System.out.println();
            }
        if (!(j%4==3)) System.out.println();

        System.out.println("\nGrab the first 1000 doubles");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextDouble() + " ");
            if (j%3==2) System.out.println();
            }
        if (!(j%3==2)) System.out.println();

        System.out.println("\nGrab the first 1000 gaussian doubles");
        r = new MersenneTwister(SEED);
        for (j = 0; j < 1000; j++)
            {
            System.out.print(r.nextGaussian() + " ");
            if (j%3==2) System.out.println();
            }
        if (!(j%3==2)) System.out.println();
        
        }
    
    }
@ Override public void nextBytes ( final byte [ ] bytes ) { for ( int x = 0 ; x < bytes . length ; x ++ ) bytes [ x ] = ( byte ) next ( 8 ) ; } public char nextChar ( ) { return ( char ) ( next ( 16 ) ) ; } public short nextShort ( ) { return ( short ) ( next ( 16 ) ) ; } public byte nextByte ( ) { return ( byte ) ( next ( 8 ) ) ; } @ Override synchronized public double nextGaussian ( ) { if ( __haveNextNextGaussian ) { __haveNextNextGaussian = false ; return __nextNextGaussian ; } double v1 , v2 , s ; do { v1 = 2 * nextDouble ( ) - 1 ; v2 = 2 * nextDouble ( ) - 1 ; s = v1 * v1 + v2 * v2 ; } while ( s >= 1 || s == 0 ) ; double multiplier = Math . sqrt ( - 2 * Math . log ( s ) / s ) ; __nextNextGaussian = v2 * multiplier ; __haveNextNextGaussian = true ; return v1 * multiplier ; } public static void main ( String args [ ] ) { int j ; MersenneTwister r ; r = new MersenneTwister ( new int [ ] { 0x123 , 0x234 , 0x345 , 0x456 } ) ; System . out . println ( "Output of MersenneTwister with new (2002/1/26) seeding mechanism" ) ; for ( j = 0 ; j < 1000 ; j ++ ) { long l = r . nextInt ( ) ; if ( l < 0 ) l += 4294967296L ; String s = String . valueOf ( l ) ; while ( s . length ( ) < 10 ) s = " " + s ; System . out . print ( s + " " ) ; if ( j % 5 == 4 ) System . out . println ( ) ; } final long SEED = 4357 ; int xx ; long ms ; System . out . println ( "\nTime to test grabbing 100000000 ints" ) ; r = new MersenneTwister ( SEED ) ; ms = System . currentTimeMillis ( ) ; xx = 0 ; for ( j = 0 ; j < 100000000 ; j ++ ) xx += r . nextInt ( ) ; System . out . println ( "Mersenne Twister: " + ( System . currentTimeMillis ( ) - ms ) + "          Ignore this: " + xx ) ; System . out . println ( "To compare this with java.util.Random, run this same test on MersenneTwisterFast." ) ; System . out . println ( "The comparison with Random is removed from MersenneTwister because it is a proper" ) ; System . out . println ( "subclass of Random and this unfairly makes some of Random's methods un-inlinable," ) ; System . out . println ( "so it would make Random look worse than it is." ) ; System . out . println ( "\nGrab the first 1000 booleans" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextBoolean ( ) + " " ) ; if ( j % 8 == 7 ) System . out . println ( ) ; } if ( ! ( j % 8 == 7 ) ) System . out . println ( ) ; System . out . println ( "\nGrab 1000 booleans of increasing probability using nextBoolean(double)" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextBoolean ( j / 999.0 ) + " " ) ; if ( j % 8 == 7 ) System . out . println ( ) ; } if ( ! ( j % 8 == 7 ) ) System . out . println ( ) ; System . out . println ( "\nGrab 1000 booleans of increasing probability using nextBoolean(float)" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextBoolean ( j / 999.0f ) + " " ) ; if ( j % 8 == 7 ) System . out . println ( ) ; } if ( ! ( j % 8 == 7 ) ) System . out . println ( ) ; byte [ ] bytes = new byte [ 1000 ] ; System . out . println ( "\nGrab the first 1000 bytes using nextBytes" ) ; r = new MersenneTwister ( SEED ) ; r . nextBytes ( bytes ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( bytes [ j ] + " " ) ; if ( j % 16 == 15 ) System . out . println ( ) ; } if ( ! ( j % 16 == 15 ) ) System . out . println ( ) ; byte b ; System . out . println ( "\nGrab the first 1000 bytes -- must be same as nextBytes" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( ( b = r . nextByte ( ) ) + " " ) ; if ( b != bytes [ j ] ) System . out . print ( "BAD " ) ; if ( j % 16 == 15 ) System . out . println ( ) ; } if ( ! ( j % 16 == 15 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 shorts" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextShort ( ) + " " ) ; if ( j % 8 == 7 ) System . out . println ( ) ; } if ( ! ( j % 8 == 7 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 ints" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextInt ( ) + " " ) ; if ( j % 4 == 3 ) System . out . println ( ) ; } if ( ! ( j % 4 == 3 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 ints of different sizes" ) ; r = new MersenneTwister ( SEED ) ; int max = 1 ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextInt ( max ) + " " ) ; max *= 2 ; if ( max <= 0 ) max = 1 ; if ( j % 4 == 3 ) System . out . println ( ) ; } if ( ! ( j % 4 == 3 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 longs" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextLong ( ) + " " ) ; if ( j % 3 == 2 ) System . out . println ( ) ; } if ( ! ( j % 3 == 2 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 longs of different sizes" ) ; r = new MersenneTwister ( SEED ) ; long max2 = 1 ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextLong ( max2 ) + " " ) ; max2 *= 2 ; if ( max2 <= 0 ) max2 = 1 ; if ( j % 4 == 3 ) System . out . println ( ) ; } if ( ! ( j % 4 == 3 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 floats" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextFloat ( ) + " " ) ; if ( j % 4 == 3 ) System . out . println ( ) ; } if ( ! ( j % 4 == 3 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 doubles" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextDouble ( ) + " " ) ; if ( j % 3 == 2 ) System . out . println ( ) ; } if ( ! ( j % 3 == 2 ) ) System . out . println ( ) ; System . out . println ( "\nGrab the first 1000 gaussian doubles" ) ; r = new MersenneTwister ( SEED ) ; for ( j = 0 ; j < 1000 ; j ++ ) { System . out . print ( r . nextGaussian ( ) + " " ) ; if ( j % 3 == 2 ) System . out . println ( ) ; } if ( ! ( j % 3 == 2 ) ) System . out . println ( ) ; } }
A bug fix for all versions of the JDK.  The JDK appears to
use all four bytes in an integer as independent byte values!
Totally wrong. I've submitted a bug report.