title: Is this a "good enough" random algorithm; why isn't it used if it's faster?
body: <p>I made a class called <code>QuickRandom</code>, and its job is to produce random numbers quickly. It's really simple: just take the old value, multiply by a <code>double</code>, and take the decimal part.</p>
  
  <p>Here is my <code>QuickRandom</code> class in its entirety:</p>
  
  <pre><code>public class QuickRandom {
      private double prevNum;
      private double magicNumber;
  
      public QuickRandom(double seed1, double seed2) {
          if (seed1 &gt;= 1 || seed1 &lt; 0) throw new IllegalArgumentException("Seed 1 must be &gt;= 0 and &lt; 1, not " + seed1);
          prevNum = seed1;
          if (seed2 &lt;= 1 || seed2 &gt; 10) throw new IllegalArgumentException("Seed 2 must be &gt; 1 and &lt;= 10, not " + seed2);
          magicNumber = seed2;
      }
  
      public QuickRandom() {
          this(Math.random(), Math.random() * 10);
      }
  
      public double random() {
          return prevNum = (prevNum*magicNumber)%1;
      }
  
  }
  </code></pre>
  
  <p>And here is the code I wrote to test it:</p>
  
  <pre><code>public static void main(String[] args) {
          QuickRandom qr = new QuickRandom();
  
          /*for (int i = 0; i &lt; 20; i ++) {
              System.out.println(qr.random());
          }*/
  
          //Warm up
          for (int i = 0; i &lt; 10000000; i ++) {
              Math.random();
              qr.random();
              System.nanoTime();
          }
  
          long oldTime;
  
          oldTime = System.nanoTime();
          for (int i = 0; i &lt; 100000000; i ++) {
              Math.random();
          }
          System.out.println(System.nanoTime() - oldTime);
  
          oldTime = System.nanoTime();
          for (int i = 0; i &lt; 100000000; i ++) {
              qr.random();
          }
          System.out.println(System.nanoTime() - oldTime);
  }
  </code></pre>
  
  <p>It is a very simple algorithm that simply multiplies the previous double by a "magic number" double. I threw it together pretty quickly, so I could probably make it better, but strangely, it seems to be working fine.</p>
  
  <p>This is sample output of the commented-out lines in the <code>main</code> method:</p>
  
  <pre><code>0.612201846732229
  0.5823974655091941
  0.31062451498865684
  0.8324473610354004
  0.5907187526770246
  0.38650264675748947
  0.5243464344127049
  0.7812828761272188
  0.12417247811074805
  0.1322738256858378
  0.20614642573072284
  0.8797579436677381
  0.022122999476108518
  0.2017298328387873
  0.8394849894162446
  0.6548917685640614
  0.971667953190428
  0.8602096647696964
  0.8438709031160894
  0.694884972852229
  </code></pre>
  
  <p>Hm. Pretty random. In fact, that would work for a random number generator in a game.</p>
  
  <p>Here is sample output of the non-commented out part:</p>
  
  <pre><code>5456313909
  1427223941
  </code></pre>
  
  <p>Wow! It performs almost 4 times faster than <code>Math.random</code>.</p>
  
  <p>I remember reading somewhere that <code>Math.random</code> used <code>System.nanoTime()</code> and tons of crazy modulus and division stuff. Is that really necessary? My algorithm performs a lot faster and it seems pretty random.</p>
  
  <p>I have two questions:</p>
  
  <ul>
  <li>Is my algorithm "good enough" (for, say, a game, where <strong>really</strong> random numbers aren't too important)?</li>
  <li>Why does <code>Math.random</code> do so much when it seems just simple multiplication and cutting out the decimal will suffice?</li>
  </ul>