title: uniform_real_distribution<float> all possible values generation
body: <p>I am currently working on importance sampling, and for testing purposes I need to be able to generate all possible values that <code>uniform_real_distribution&lt;float&gt;</code> may generate for the interval [0,1] (yes it is closed from the right too). My idea was to generate integer numbers which I can then convert to floating point numbers. From the tests I made it seems that there is a perfect bijection between uniform single-precision floats in [0,1] and integers in [0,2^24] (I am a bit bothered by the fact that it is not [0,2^24-1] and I am still trying to figure out why, my best guess is that 0 is simply special for floats and 1 to 2^24 all result in floats that have the same exponent). My question is whether the floats generated this way are exactly the floats that can be generated from <code>uniform_real_distribution&lt;float&gt;</code>. You can find my integer &lt;-> float tests below:</p>
  
  <pre><code>void floatIntegerBitsBijectionTest()
  {
      uint32 two24 = 1 &lt;&lt; 24;
      bool bij24Bits = true;
      float delta = float(1.0) / float(two24);
      float prev = float(0) / float(two24);
      for (uint32 i = 1; i &lt;= two24; ++i)
      {
          float uintMap = float(i) / float(two24);
          if (uintMap - prev != delta || uint32(uintMap*float(two24)) != i)
          {
              std::cout &lt;&lt; "No bijection exists between uniform floats in [0,1] and integers in [0,2^24].\n";
              bij24Bits = false;
              break;
          }
          prev = uintMap;
      }
      if(bij24Bits) std::cout &lt;&lt; "A bijection exists between uniform floats in [0,1] and integers in [0,2^24].\n";
      std::cout &lt;&lt; "\n";
  
      uint32 two25 = 1 &lt;&lt; 25;
      bool bij25Bits = true;
      delta = float(1.0) / float(two25);
      prev = float(0) / float(two25);
      for (uint32 i = 1; i &lt;= two25; ++i)
      {
          float uintMap = float(i) / float(two25);
          if (uintMap - prev != delta || uint32(uintMap*float(two25)) != i)
          {
              std::cout &lt;&lt; "No bijection exists between uniform floats in [0,1] and integers in [0,2^25].\n";
              if (i == ((1 &lt;&lt; 24) + 1)) std::cout &lt;&lt; "The first non-uniformly distributed float corresponds to the integer 2^24+1.\n";
  
              bij25Bits = false;
              break;
          }
          prev = uintMap;
      }
      if (bij25Bits) std::cout &lt;&lt; "A bijection exists between uniform floats in [0,1] and integers in [0,2^25].\n";
      std::cout &lt;&lt; "\n";
  
  
      bool bij25BitsS = true;
      delta = 1.0f / float(two24);
      prev = float(-two24) / float(two24);
      for (int i = -two24+1; i &lt;= two24; ++i)
      {
          float uintMap = float(i) / float(two24);
          if (uintMap - prev != delta || int(uintMap*float(two24)) != i)
          {
              std::cout &lt;&lt; i &lt;&lt; " " &lt;&lt; uintMap - prev &lt;&lt; " " &lt;&lt; delta &lt;&lt; "\n";
              std::cout &lt;&lt; "No bijection exists between uniform floats in [-1,1] and integers in [-2^24,2^24].\n";
              bij25BitsS = false;
              break;
          }
          prev = uintMap;
      }
      if (bij25BitsS) std::cout &lt;&lt; "A bijection exists between uniform floats in [-1,1] and integers in [-2^24,2^24].\n";
  }
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>Somewhat relevant:</p>
  
  <p><a href="https://crypto.stackexchange.com/questions/31657/uniformly-distributed-secure-floating-point-numbers-in-0-1">https://crypto.stackexchange.com/questions/31657/uniformly-distributed-secure-floating-point-numbers-in-0-1</a></p>
  
  <p><a href="http://xoroshiro.di.unimi.it/random_real.c" rel="nofollow noreferrer">http://xoroshiro.di.unimi.it/random_real.c</a></p>
  
  <p><a href="https://www.reddit.com/r/programming/comments/29ducz/obtaining_uniform_random_floats_is_trickier_than/" rel="nofollow noreferrer">https://www.reddit.com/r/programming/comments/29ducz/obtaining_uniform_random_floats_is_trickier_than/</a></p>
  
  <p><a href="https://lemire.me/blog/2017/02/28/how-many-floating-point-numbers-are-in-the-interval-01/" rel="nofollow noreferrer">https://lemire.me/blog/2017/02/28/how-many-floating-point-numbers-are-in-the-interval-01/</a></p>
  
  <p>EDIT 2:</p>
  
  <p>I finally managed to figure out what <code>uniform_real_distribution&lt;float&gt;</code> does at least when used with the <code>mt19937</code> engine when used with its default template arguments (I am talking about the implementation that comes with VS2017). Sadly, it simply generates a random integer number in [0,2^32-1] casts it to float and then divides it by 2^32. Needless to say this produces non-uniformly distributed floating point numbers. I am guessing, however, that this works for most practical purposes unless one is working close to the precision of the deltas between generated numbers.</p>