# Differences

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

 floating-point-equality [2017/11/21 10:28]awf floating-point-equality [2018/09/05 14:53]awf [But my case is more subtle than that] Both sides previous revision Previous revision 2018/09/05 15:14 awf 2018/09/05 14:53 awf [But my case is more subtle than that] 2017/11/21 12:27 awf 2017/11/21 10:28 awf 2017/11/21 10:26 awf 2017/04/19 12:15 awf 2017/04/19 12:15 awf 2015/03/10 02:01 awf 2015/03/10 02:01 awf 2015/03/10 02:00 awf 2015/03/10 01:56 awf 2015/03/10 01:54 awf created Next revision Previous revision 2018/09/05 15:14 awf 2018/09/05 14:53 awf [But my case is more subtle than that] 2017/11/21 12:27 awf 2017/11/21 10:28 awf 2017/11/21 10:26 awf 2017/04/19 12:15 awf 2017/04/19 12:15 awf 2015/03/10 02:01 awf 2015/03/10 02:01 awf 2015/03/10 02:00 awf 2015/03/10 01:56 awf 2015/03/10 01:54 awf created Last revision Both sides next revision Line 61: Line 61: - Even here, you can think about what a better value to compare to might be.   First note that sin(x)/x works fine for all normalized floats except zero, so you can avoid a dependency on fabs and a definition of epsilon by just comparing to zero. + Even here, you can think about what a better value to compare to might be.   First note that sin(x)/x works fine for all floats except zero, so you can avoid a dependency on fabs and a definition of epsilon by just comparing to zero. But perhaps the profiler has told you that a big chunk of program time is spent in computing sin() and dividing, and furthermore you know that most times it's called with values near zero.  Well then, let's do what we do with any special function that goes slow: chop up the domain and special case.   It's true that sin(x)/x is exactly floating point 1.0 when x is small.  In fact, compute the taylor series, see that But perhaps the profiler has told you that a big chunk of program time is spent in computing sin() and dividing, and furthermore you know that most times it's called with values near zero.  Well then, let's do what we do with any special function that goes slow: chop up the domain and special case.   It's true that sin(x)/x is exactly floating point 1.0 when x is small.  In fact, compute the taylor series, see that Line 77: Line 77: } } + + 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." + + + 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; + } + + === And templates? === === And templates? ===