title: How to determine whether number is exactly representable in floating-point?
body: <p>Since float numbers are base-2 numeral system then it's not possible to represent <code>0.24F</code> directly as the same it's not possible to represent <code>1/3</code> in decimal system without <a href="https://en.wikipedia.org/wiki/Repeating_decimal" rel="nofollow noreferrer">recurring decimal period</a> i.e. <code>1/3=0.3333...</code> or <code>0.(3)</code>.</p>
  
  <p>So the float number <code>0.24F</code> when printed back to decimal representation is shown as <code>0.23</code> with a change due to rounding:</p>
  
  <pre><code>println(0.24F) =&gt; 0.23999999463558197021484375
  </code></pre>
  
  <p>while <code>0.25F</code> can be shown directly:</p>
  
  <pre><code>println(0.25F) =&gt; 0.25
  </code></pre>
  
  <p>But how can I determine that a number is exactly representable?</p>
  
  <pre><code>isExactFloat(0.25F) ==&gt; true
  isExactFloat(0.24F) ==&gt; false
  </code></pre>
  
  <p>Maybe Java API has already some function to do that?</p>
  
  <p><em>UPD</em>
  Here is a code which shows float numbers in range [-4, 4] with their internal representation:</p>
  
  <pre><code>public class FloatDestructure {
      public static void main(String[] args) {
          BigDecimal dec = BigDecimal.valueOf(-4000L, 3);
          BigDecimal incr = BigDecimal.valueOf(1L, 3);
          for (int i = 0; i &lt;= 8000; i++) {
              double dbl = dec.doubleValue();
              floatDestuct(dbl, dec);
              dec = dec.add(incr);
          }
  
      }
      static boolean isExactFloat(double d) { return d == (float) d; }
  
      static void floatDestuct(double val, BigDecimal dec) {
          float value = (float) val;
          int bits = Float.floatToIntBits(value);
          int sign = bits &gt;&gt;&gt; 31;
          int exp = (bits &gt;&gt;&gt; 23 &amp; ((1 &lt;&lt; 8) - 1)) - ((1 &lt;&lt; 7) - 1);
          int mantissa = bits &amp; ((1 &lt;&lt; 23) - 1);
          float backToFloat = Float.intBitsToFloat((sign &lt;&lt; 31) | (exp + ((1 &lt;&lt; 7) - 1)) &lt;&lt; 23 | mantissa);
          boolean exactFloat = isExactFloat(val);
          boolean exactFloatStr = Double.toString(value).length() &lt;= 7;
          System.out.println(dec.toString() + " " + (double) val + " " + (double) value + " sign: " + sign + " exp: " + exp + " mantissa: " + mantissa + " " + Integer.toBinaryString(mantissa) + " " + (double) backToFloat + " " + exactFloat + " " + exactFloatStr);
      }
  }
  </code></pre>
  
  <p>When mantissa is zero then the float is definitely exact. But in other cases like <code>-0.375</code> or <code>-1.625</code> it's not so clear.</p>