which basically rounds a value to the nth floating point.
It also works fine in most cases, however for example roundToSignificant(900000.05f, 1) returns 900000.13 but it should return 900000.10.
When debugging through the code the issue seems to happen at the very last line of the function so the values there look like this -> return (float)(9000001/10.000000);
I know calculating around with float values isn't exactly accurate but I would like to know if there is any way to solve this issue here to get the desired result?
> You might have to work with me here because I'm kind of lost on how you got your numbers.
Why, do you get different values? It could be because you are using a different debugger/platform/compiler (Windows 7, VS2010).
> 900000.10 may not have a floating point representation at all; what you would get is the nearest representable floating point value.
So it might not be an inaccurate value afterall, it just doesn't get more precise? I would actually be okay with that as long as other values in the area near that value get the same value assigned (for storing purposes).
> So it might not be an inaccurate value afterall, it just doesn't get more precise?
Yes. It doesn't get more precise than half a ulp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include <iostream>
#include <boost/math/special_functions/next.hpp>
int main()
{
constfloat lb = 900000.0 ;
constfloat ub = boost::math::float_next( lb + 1.0 ) ;
std::cout << "number of ulps between " << lb << " and " << ub << " is "
<< boost::math::float_distance( lb, ub ) << "\n\n" ;
int n = 0 ;
for( float f = lb ; f < ub ; f = boost::math::float_next(f) )
std::cout << std::setw(2) << ++n << ". " << std::fixed << f << '\n' ;
}
On my implementation:
number of ulps between 900000 and 900001 is 16
1. 900000.000000
2. 900000.062500
3. 900000.125000
4. 900000.187500
5. 900000.250000
6. 900000.312500
7. 900000.375000
8. 900000.437500
9. 900000.500000
10. 900000.562500
11. 900000.625000
12. 900000.687500
13. 900000.750000
14. 900000.812500
15. 900000.875000
16. 900000.937500
> I would actually be okay with that as long as other values in the area
> near that value get the same value assigned
The IEEE 754 specification—followed by all modern floating-point hardware—requires that the result of an elementary arithmetic operation (addition, subtraction, multiplication, division, and square root since 1985, and FMA since 2008) be within 0.5 ULP of the mathematically exact result, using John Harrison's definition—that is, that it be the best possible result.
- http://en.wikipedia.org/wiki/Unit_in_the_last_place