I was working on paper subtracting the floating-point numbers 1.0 - 1.0.
I aligned the exponents, then subtracted the mantissa. Which is zero and my result comes out to 1.0. Obviously the result is supposed to be 0. How is that possible if I can't normalize a mantissa of 0, there are no bits to shift?
Exponents are aligned: 0x7F, 0x7F
Subtracting both mantissas:
0x800000 - 0x800000 = 0
Mantissa is 0x0, and there are no bits in mantissa to shift left or right to normalize.
Exponent: 0x7F Mantissa: 0x0
1.0
It is awkward to work with floating-point numbers using the bits that represent them instead of using the mathematical form, ±F•be, where b is a fixed base (two for binary floating-point), e is an integer in a specified range, and F is a base-b numeral of fixed length and range. F is called the significand.1
In the mathematical form, 1.0 is +1.000…000•20, and subtracting +1.000…000•20 from +1.000…000•20 yields +0.000…000•20 (the exponent does not matter), and, when we encode that int the IEEE-754 single precision format (binary32), we get the bits 0000…0000 (sign bit 0, exponent field 0000000, significand field 0000…0000).
If you are going to work with the bits directly, you have to develop more details for an algorithm for that. Once you have a result, you must encode it properly. The rules for encoding a binary32 number include:
Thus, since you had a significand of 0, you should have set the exponent field to 0.
1 “Significand” is the preferred term for the fraction portion of a floating-point representation. “Mantissa” is an old term for the fraction portion of a logarithm. Significands are linear. Mantissas are logarithmic.