I'm working on a cryptography application ,using Crypto++
As an obscure part of this application, I need to determine the maximum number of unique float values that can exist within a certain numeric range.
Obviously there are infinite numbers between 0
and 1
in reality - but not all of them can be represented by a unique float value.
I have a minimum float value, and a maximum float value.
I need to determine the number of possible float values inside this range.
This is tricky, because floating-point values are spaced further apart, the farther you get from 0
.
For example, the number of possible floating-point values between 0
and 1
, is very different from the number of floating-point values between 100,000
and 100,001
For my purposes, I want the count to include both the min and max values as well.
But an algorithm that produces an exclusive count would be just as useful, as I could simply add 1
or 2
as needed.
Additional concern:
What if 0
is within the range?
For example, if the minimum value is -2.0, and the maximum value is positive 2.0, I don't want to count 0
twice (once for 0
, and again for -0
).
Additionally, what problems would arise if the minimum or maximum values are +/-infinity?
(I'll probably just throw an exception if the minimum or maximum are NaN).
uint32_t RangeValueCount ( float fMin , float fMax )
{
if ( fMin > fMax )
swap ( fMin , fMax ) ; // Ensure fMin <= fMax
// Calculate the number of possible floating-point values between fMin and fMax.
return ( *reinterpret_cast < uint32_t* > ( &fMax ) -
*reinterpret_cast < uint32_t* > ( &fMin ) ) + 1 ;
// This algorithm is obviously unsafe, assumes IEEE 754
// How should I account for -0 or infinity?
}
If this problem can be solved, I presume the solution would be equally applicable to double values (and possibly long double values, but that might be a little more complex due to 80-bit integer values etc.)
Is tricky, potentially you could try to use
std::nexttoward(from_starting, to_end);
in a loop and count until it ends. Haven't tried this myself and it will take a long time to finish. If you do this make sure you check for the error flags, see: http://en.cppreference.com/w/cpp/numeric/math/nextafterHere is code that handles all finite numbers. It expects IEEE 754 arithmetic. I have replaced my previous version with simpler, cleaner code. Instead of two implementations of the distance calculation, this has two implementations of converting a floating-point number to its encoding (one by copying the bits, one by mathematically manipulating it). After that, the distance calculation is fairly simple (negative values have to be adjusted, and then the distance is simply a subtraction).