If we have a double-precision value in C++ and do a static_cast<float> on it, will the returned value always be smaller in absolute value? My intuition behind this says yes for the following reasons.
- The set of possible single precision exponents is strictly a subset of double precision exponents
- In converting the double precision mantissa to single precision, bits are probably truncated off then end to fit the double's mantissa into the float's mantissa. However, it's not impossible that rounding up is sometimes done to the next highest floating point value if it's more accurate. Perhaps this is system-dependent, or defined in some standard.
I have experimented some numerically with this in the following program. It appears that sometimes, rounding up happens, and other times, round down.
Where can I find more info about how I can expect this rounding to behave? Does it always round to the nearest float?
#include <cmath>
#include <iostream>
int main() {
// Start testing double precision values starting at x, going up to max
double x = 0.98;
constexpr double max = 1e10;
// Loop over many possible double-precision values, print out
// if casting to float ever produced a larger number.
int output_counter = 0; // output every n steps
constexpr int output_interval = 100000000;
std::cout.precision(17);
while (x < max) {
// volatile to ensure compiler doesn't optimize this out
volatile float xprime = static_cast<float>(x);
double xprimeprime = static_cast<double>(xprime);
if (xprimeprime > x)
std::cout << "Found a round up! x=" << x << ", xprime = "<< xprime << std::endl;
// Go to the next higher double precision value
x = std::nextafter(x, std::numeric_limits<double>::infinity());
output_counter++;
if (output_counter == output_interval) {
std::cout << x << std::endl;
output_counter = 0;
}
}
}