title: Does the same floating-point calculation producing different results when performed twice indicate IEEE 754 non-conformance?
body: <p>In a specific online judge running 32-bit GCC 7.3.0, this:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  volatile float three = 3.0f, seven = 7.0f;
  
  int main()
  {
      float x = three / seven;
      std::cout &lt;&lt; x &lt;&lt; '\n';
      float y = three / seven;
      std::cout &lt;&lt; (x == y) &lt;&lt; '\n';
  }
  </code></pre>
  
  <p>Outputs</p>
  
  <pre><code>0.428571
  0
  </code></pre>
  
  <p>To me this seems like it violates IEEE 754, since the standard requires basic operations to be correctly rounded. Now I know there are a couple reasons for IEEE 754 floating-point calculations to be non-deterministic as discussed <a href="https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/" rel="nofollow noreferrer">here</a>, but I don't see how any of them applies to this example. Here are some of the things I considered:</p>
  
  <ul>
  <li>Excess precision and contraction: I'm doing a single calculation and assigning the result to a <code>float</code>, which should force both of the values to be rounded to <code>float</code> precision.</li>
  <li>Compile-time calculations: <code>three</code> and <code>seven</code> are <code>volatile</code> so both calculations must be done at runtime.</li>
  <li>Floating-point flags: The calculations are done in the same thread almost immediately after each other, so the flags should be the same.</li>
  </ul>
  
  <p>Does this necessarily indicate that the online judge system doesn't conform to IEEE 754?</p>
  
  <p>Also, removing the statement printing <code>x</code>, adding a statement to print <code>y</code>, or making <code>y</code> volatile all changes the result. This seems to contradict my understanding of the C++ standard which I think requires the assignments to round off any excess precision.</p>
  
  <p>Thanks to geza for pointing out that this is a <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323" rel="nofollow noreferrer">known issue</a>. I would still like a definitive answer on whether this conforms to the C++ standard and IEEE 754 though, since the C++ standard appears to require assignments to round off excess precision. Here's the quote from draft N4860 [expr.pre]:</p>
  
  <blockquote>
    <p>The values of the floating-point operands and the results of floating-point expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.<sup>50</sup></p>
    
    <p>50) The cast and assignment operators must still perform their specific conversions as described in 7.6.1.3, 7.6.3, 7.6.1.8 and 7.6.19.</p>
  </blockquote>