title: Why such different and unsymmetrical rules for defining values at which flush to zero and flush to infinity occurs for floating-point?
body: <p>Why <code>Double.MIN_VALUE == Math.ulp(Double.MIN_VALUE) // 4.9E-324</code></p>
  
  <p>while <code>Double.MAX_VALUE != Math.ulp(Double.MAX_VALUE)</code></p>
  
  <pre><code>// Double.MAX_VALUE           = 1.7976931348623157E308
  // Math.ulp(Double.MAX_VALUE) = 1.9958403095347198E292    !!!
  </code></pre>
  
  <p><em>I thought that flush to zero occurs at floating-point values less than <code>Double.MIN_VALUE - Math.ulp(Double.MIN_VALUE)</code>.</em> But this is not true, besides both Double.MIN_VALUE and Math.ulp(Double.MIN_VALUE) are equal. In reality flush to zero occurs at <code>Math.ulp(Double.MIN_VALUE)/2</code> exactly and below (smaller than that).</p>
  
  <p>But flush to infinity occurs at <code>Double.MAX_VALUE + Math.ulp(Double.MAX_VALUE)</code>. Interesting thing to note is that <code>Double.MAX_VALUE + Integer.MAX_VALUE ==  Double.MAX_VALUE</code> (because Integer.MAX_VALUE &lt; Math.ulp(Double.MAX_VALUE) ).</p>
  
  <p>Why logic for flush to zero is different from flush to infinity? I mean w<strong>hy flush to zero is not</strong> <code>Double.MIN_VALUE - Math.ulp(Double.MIN_VALUE)/2 // same as Double.MIN_VALUE</code> - <strong><em>symmetrically</em> to flush to infinity which occurs at</strong> <code>Double.MAX_VALUE + Math.ulp(Double.MAX_VALUE)/2</code> and <code>-Double.MAX_VALUE - Math.ulp(Double.MAX_VALUE)/2</code> ?</p>
  
  <p>My research: <a href="https://stackoverflow.com/questions/34667932/minimum-floating-point-number-closest-to-zero">this</a> and <a href="https://stackoverflow.com/questions/26448637/how-are-upper-and-lower-bounds-for-floating-point-numbers-determined">this</a> are c++ specific only. </p>