The cvtsd2ss
instruction uses the FPU’s rounding mode to do the conversion. The default rounding mode is round-to-nearest-even.
In order to follow the algorithm, it helps to keep in mind the information at the IEEE 754-1985 Wikipedia page, especially the diagrams representing the layout.
First, the exponent of the target float
is computed: the double
type has a wider range than float
, so the result may be 0.0f
(or a denormal) for a very small double
, or an infinite value for a very large double.
For the usual case of a normal double
being converted to a normal float
(roughly, when the unbiased exponent of the double
can be represented in the 8 bits of a single-precision representation), the first 23 bits of the destination significand start out the same as the most significant of the original number’s 52-bit significand.
Then there is the problem of rounding:
-
if the left-over bits are below
10..0
, then the target significand is left as-is. -
If the left-over bits are above
10..0
, then the target significand is incremented. If incrementing it makes it overflow (because it is already1..1
), then the carry is propagated into the exponent bits. This produces the correct result because of the careful way the IEEE 754 layout has been designed. -
If the bits left over are exactly
10..0
, then thedouble
is exactly midway between twofloat
s. Of these two choices, the one with the last bit0
(“even”) is chosen.
After this step, the target significand corresponds to the float
nearest to the original double
.
The directed rounding modes are only simpler. The case where the target float
is a denormal is slightly more complicated (one must be careful to avoid “double-rounding”).