I was trying to figure it out for my audio application if float
can be used to represent correctly the range of parameters I'll use.
The "biggest" mask it needs is for frequency params, which is positive, and allow max two digits as mantissa (i.e. from 20.00 hz to 22000.00 hz). Conceptually, the following digits will be rounded out, so I don't care for them.
So I made this script to check the first number that collide in single precision:
float temp = 0.0;
double valueDouble = 0.0;
double increment = 1e-2;
bool found = false;
while(!found) {
double oldValue = valueDouble;
valueDouble += increment;
float value = valueDouble;
// found
if(temp == value) {
std::cout << "collision found: " << valueDouble << std::endl;
std::cout << " collide with: " << oldValue << std::endl;
std::cout << "float stored as: " << value << std::endl;
found = true;
}
temp = value;
}
and its seems its 131072.02
(with 131072.01
, stored as the same 131072.015625
value), which is far away than 22000.00. And it seems I would be ok using float.
But I'd like to understand if that reasoning is correct. It is?
The whole problem would be if I set a param of XXXXX.YY (7 digits
) and it collides with some other numbers having a less number of digits (because single precision
only guarantee 6 digits
)
Note: of course numbers such as 1024.0002998145910169114358723163604736328125
or 1024.000199814591042013489641249179840087890625
collide, and they are within the interval, but they do it at a longer significative digits than my required mantissa, so I don't care.