Set aside the sign; it the same for both formats.
If the exponent field is all ones:
- The datum is an infinity or NaN.
- If the significand field is all zeros, the datum is an infinity. Return a number in the destination format with the sign from above, an exponent field of all ones, and a significand field of all zeros.
- Otherwise, the datum is a NaN. Return a number in the destination format with the sign from above, an exponent field of all ones, and a significand changed in some reasonable way (this is not fully defined by the standards).
If the exponent field is neither all ones nor all zeros:
- Take the exponent field as a binary numeral (for example, 110111 is 103). Subtract the bias for that format (127 for IEEE-754 binary32, 1023 for binary64). That gives you the actual exponent.
- Form a binary number from “1.” followed by the bits of the significand field, such as “1.00001111000000000000001”. That gives you the actual significand. Continue below.
If the exponent field is all zeros:
- Start with 1 and subtract the bias for the format. That gives you the actual exponent.
- Form a binary number from “0.” followed by the bits of the significand field, such as “0.00001111000000000000001”. That gives you the actual significand. Continue below.
If the actual significand is zero, return a number in the destination format formed with the sign from above, all zeros in the exponent field, and all zeros in the significand field.
If the actual significand does not start with “1.”, then shift it left one bit (multiply it by two) and subtract one from the actual exponent. Repeat this until the significand starts with “1.”
If the actual exponent equals or exceeds the maximum finite exponent for the destination format (127 for binary32, 1023 for binary64):
- If it exceeds the maximum finite exponent, return an infinity, as described above.
- If it just equals the maximum finite exponent, round the significand to the number of significand bits in the destination format (24 for binary32, 53 for binary64) (using whatever rounding rule is in effect, often round-to-nearest-ties-to-even). If this causes it to round up to (binary) “10.”, return an infinity as above. Otherwise, continue below.
If the actual exponent equals or exceeds the minimum normal exponent for the destination format (−126 for binary32, −1022 for binary64):
- Round the significand to the number of significand bits in the destination format.
- Remove the leading “1.” from the significand and use the bits after the “.” (23 bits for binary32, 52 for binary64) to form the significand encoding.
- Add the bias for the format to the exponent to form the biased exponent.
- Return a number in the destination format with the sign from above, the biased exponent, and the significand encoding.
Otherwise, the result is subnormal (and may round to zero):
- Let S be the minimum normal exponent minus the actual exponent.
- Let P be the number of bits in the significand field in the destination format (23 for binary32, 52 for binary64) minus S. (P+1 is the number of bits available in the destination format for the significand, given the subnormal exponent. It may be zero or negative, but the rounding below may effectively bring it to 1.)
- Multiply the significand by 2P and round it to an integer (using whatever rounding rule is in effect).
- Return a number in the destination format with the sign from above, an exponent field of all zeros, and a significand field with the rounded significand from just above (taken as an integer, represented in binary).
floattodoubleis not expected to lose precision. It is onlydoubletofloatthat has a real concern. - chux - Reinstate Monica