Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
floating-point-equality [2017/11/21 12:27]
awf
floating-point-equality [2018/09/05 15:14]
awf
Line 49: Line 49:
 But hang on, you're on a platform which will give you line number here when you get the divby0 right? ​   But hang on, you're on a platform which will give you line number here when you get the divby0 right? ​  
 So the assert is superfluous -- just enable exceptions on divide by zero, underflow, and overflow. So the assert is superfluous -- just enable exceptions on divide by zero, underflow, and overflow.
 +
 +And there'​s also a very simple case. If I stored 0.3f somewhere, I expect to get it back.  It's irrelevant that 0.3f doesn'​t have an exact binary representation -- whatever it translates to, I should get exactly that back
 +<code C++>
 +void my_unit_test() {
 +  my_matrix<​2,​2,​float>​ a = {3.0f, 1.1f, 2.2f, 4.0f};
 +  TEST_ASSERT_EQ_APPROX(a(0,​0),​ 3.0f, 1e-8f); // No, no, no.  There is no reason for the stored value to be different.
 +  TEST_ASSERT_EQ(a(0,​0),​ 3.0f); // I gave you whatever 3.0f is.  I want it back.
 +}
 +</​code>​
 +You may worry about excess precision on x86, but there'​s no computation going on here, so we can and should ask for exact equality.
  
 ==== But my case is more subtle than that ==== ==== But my case is more subtle than that ====
Line 77: Line 87:
 } }
 </​code>​ </​code>​
 +
 +It's a good idea then to write a blog post about the issue, because Toby Sharp might comment (see below) and point out that there is a much better choice:
 +
 +> "... since we need some kind of test for x=0 anyway, I don't see why we shouldn'​t take the opportunity to improve accuracy in this vicinity. And yes, it only costs 2 multiplies which is less than using the sin in those cases. So we are improving both performance and accuracy in the range (0, threshold). threshold is chosen to be the largest value such that the quadratic approximation is as good as the direct evaluation."​
 +
 +<code C++>
 +float sinc(float x) { 
 +  // Toby's threshold, determined through binary search as the best value for minimizing absolute error
 +  if (std::​abs(x) < 0.0406015441f)
 +      return 1.0f - (x * x) * (1.0f / 6.0f);
 +  else
 +      return std::sin(x) / x;
 +
 +</​code>​
 +
  
 === And templates? === === And templates? ===
Line 96: Line 121:
 } }
 </​code>​ </​code>​
 +
 +See also
 +* https://​stackoverflow.com/​questions/​51134021/​floating-point-equality
  
 ~~DISCUSSION~~ ~~DISCUSSION~~