title: Analysis of float/double precision in 32 decimal digits
body: <p>From a .c file of another guy, I saw this:</p>
  
  <pre><code>const float c = 0.70710678118654752440084436210485f;
  </code></pre>
  
  <p>where he wants to avoid the computation of <code>sqrt(1/2)</code>.</p>
  
  <p>Can this be really stored somehow with plain <code>C/C++</code>? I mean without loosing precision. It seems impossible to me.</p>
  
  <p>I am using C++, but I do not believe that precision difference between this two languages are too big (if any), that' why I did not test it.</p>
  
  <p>So, I wrote these few lines, to have a look at the behaviour of the code:</p>
  
  <pre><code>std::cout &lt;&lt; "Number:    0.70710678118654752440084436210485\n";
  
  const float f = 0.70710678118654752440084436210485f;
  std::cout &lt;&lt; "float:     " &lt;&lt; std::setprecision(32) &lt;&lt; f &lt;&lt; std::endl;
  
  const double d = 0.70710678118654752440084436210485; // no f extension
  std::cout &lt;&lt; "double:    " &lt;&lt; std::setprecision(32) &lt;&lt; d &lt;&lt; std::endl;
  
  const double df = 0.70710678118654752440084436210485f;
  std::cout &lt;&lt; "doublef:   " &lt;&lt; std::setprecision(32) &lt;&lt; df &lt;&lt; std::endl;
  
  const long double ld = 0.70710678118654752440084436210485;
  std::cout &lt;&lt; "l double:  " &lt;&lt; std::setprecision(32) &lt;&lt; ld &lt;&lt; std::endl;
  
  const long double ldl = 0.70710678118654752440084436210485l; // l suffix!
  std::cout &lt;&lt; "l doublel: " &lt;&lt; std::setprecision(32) &lt;&lt; ldl &lt;&lt; std::endl;
  </code></pre>
  
  <p>The output is this:</p>
  
  <pre><code>                   *       ** ***
                     v        v v
  Number:    0.70710678118654752440084436210485    // 32 decimal digits
  float:     0.707106769084930419921875            // 24 &gt;&gt;      &gt;&gt;
  double:    0.70710678118654757273731092936941
  doublef:   0.707106769084930419921875            // same as float
  l double:  0.70710678118654757273731092936941    // same as double
  l doublel: 0.70710678118654752438189403651592    // suffix l
  </code></pre>
  
  <p>where <code>*</code> is the last accurate digit of <code>float</code>, <code>**</code> the last accurate digit of <code>double</code> and <code>***</code> the last accurate digit of <code>long double</code>. </p>
  
  <p>The output of <code>double</code> has 32 decimal digits, since I have set the precision of <code>std::cout</code> at that value.</p>
  
  <p><code>float</code> output has 24, as expected, as said <a href="https://stackoverflow.com/questions/19292283/0-1-float-is-greater-than-0-1-double-i-expected-it-to-be-false">here</a>:</p>
  
  <pre><code>float has 24 binary bits of precision, and double has 53.
  </code></pre>
  
  <p>I would expect the last output to be the same with the pre-last, i.e. that the <code>f</code> suffix would not prevent the number from becoming a <code>double</code>. I <em>think</em> that when I write this:</p>
  
  <pre><code>const double df = 0.70710678118654752440084436210485f;
  </code></pre>
  
  <p>what happens is that first the number becomes a <code>float</code> one and then stored as a <code>double</code>, so after the 24th decimal digits, it has zeroes and that's why the <code>double</code> precision stops there.</p>
  
  <p>Am I correct?</p>
  
  <p>From <a href="https://stackoverflow.com/questions/5199338/what-is-the-significance-of-0-0f-when-initializing-in-c">this</a> answer I found some relevant information:</p>
  
  <pre><code>float x = 0 has an implicit typecast from int to float.
  float x = 0.0f does not have such a typecast.
  float x = 0.0 has an implicit typecast from double to float.
  </code></pre>
  
  <hr>
  
  <p>[EDIT]</p>
  
  <p>About <code>__float128</code>, it is not standard, thus it's out of the competition. See more <a href="https://stackoverflow.com/questions/23654693/print-float128-without-using-quadmath-snprintf">here</a>.</p>