Normalisation of floating-point numbers

A2 · 11 min

The same number can be written in floating point in many ways, just as 0.5×1030.5 \times 10^{3}, 0.05×1040.05 \times 10^{4} and 0.005×1050.005 \times 10^{5} are all 500. Normalisation picks one standard form: the one that wastes no mantissa bits. Paper 3 asks you to recognise whether a number is normalised, to normalise it by shifting the mantissa and adjusting the exponent, and to explain why normalisation is done. It builds directly on floating-point numbers.

Many representations of one number

With an 8-bit mantissa and a 4-bit exponent, 0.250.25 can be stored as:

MantissaExponentValue
010000001111 (−1-1)12×2−1=0.25\tfrac12 \times 2^{-1} = 0.25
001000000000 (00)14×20=0.25\tfrac14 \times 2^{0} = 0.25
000100000001 (11)18×21=0.25\tfrac18 \times 2^{1} = 0.25
000010000010 (22)116×22=0.25\tfrac1{16} \times 2^{2} = 0.25

Every row is correct, but only the first uses the mantissa well. In the others, the 0s after the sign bit are just copies of the sign; they store no information and take up places that could hold significant bits.

What a normalised number looks like

Definition

A floating-point number is normalised when the first two bits of the mantissa are different:

  • a positive normalised mantissa starts 01
  • a negative normalised mantissa starts 10

Put in terms of value, a normalised mantissa MM satisfies 12≤M<1\tfrac12 \le M < 1 if positive and −1≤M<−12-1 \le M < -\tfrac12 if negative.

A mantissa starting 00 or 11 is not normalised: the second bit merely repeats the sign.

Watch out

The negative case catches people out. 11010000 is not normalised, even though it has a 1 in the second place; the second bit copies the sign bit. Normalised negatives begin 10.

Why numbers are normalised

Key result

Normalisation:

  1. Maximises precision. Redundant leading sign bits are removed, so the mantissa holds as many significant bits as possible for its length.
  2. Gives a unique representation of each number, so two stored values can be compared directly and there is no ambiguity.
  3. Makes arithmetic simpler and more consistent, because every operand is in the same form.

Precision is the reason that matters most. Suppose a calculation produces 0.00010110112×200.0001011011_2 \times 2^{0} and there is an 8-bit mantissa. Without normalising, the mantissa can only hold 0.0001011, keeping four significant bits (1011) and losing the final 011. Normalised as 0.1011011×2−30.1011011 \times 2^{-3}, the mantissa 01011011 keeps all seven significant bits.

How to normalise

The rule is a single trade: moving the mantissa one place left doubles it, so the exponent must go down by 1 to keep the value the same.

Normalising a floating-point number
  1. Look at the first two bits of the mantissa. If they differ (01 or 10), it is already normalised.
  2. Otherwise, shift all mantissa bits left one place, putting a 0 in the rightmost place.
  3. Subtract 1 from the exponent for every place shifted.
  4. Repeat until the first two bits differ. (A positive number ends up starting 01, a negative one 10. The sign bit never changes, because every bit shifted out is just a copy of it.)
  5. Write the new exponent in two's complement, and check it still fits in the exponent's width. If it does not, the number cannot be normalised in this format.
  6. Check that the value is unchanged.

A shortcut: count how many places the first 01 or 10 pattern is from the start, shift by that many places at once, and subtract that number from the exponent.

Normalising a positive number

A floating-point number has an 8-bit mantissa 00011010 and a 4-bit exponent 0101, both in two's complement. Normalise it.

Solution

The mantissa starts 00, so it is not normalised. The first 1 is in the fourth place, so the mantissa must move 2 places left to start 01.

Mantissa: 00011010 → 01101000.

Exponent: 5−2=35 - 2 = 3 → 0011.

MantissaExponent
011010000011

Check: before, 0.00110102×25=0.203125×32=6.50.0011010_2 \times 2^{5} = 0.203125 \times 32 = 6.5. After, 0.11010002×23=0.8125×8=6.50.1101000_2 \times 2^{3} = 0.8125 \times 8 = 6.5.

Normalising a negative number

Normalise the floating-point number with mantissa 11100110 and exponent 0010.

Solution

The mantissa starts 11, so it is not normalised. Shifting left: 11100110 → 11001100 (still 11) → 10011000 (now 10). That is 2 places.

Exponent: 2−2=02 - 2 = 0 → 0000.

MantissaExponent
100110000000

Check: before, (−1+12+14+132+164)×22=−0.203125×4=−0.8125(-1 + \tfrac12 + \tfrac14 + \tfrac1{32} + \tfrac1{64}) \times 2^{2} = -0.203125 \times 4 = -0.8125. After, (−1+18+116)×20=−0.8125(-1 + \tfrac18 + \tfrac1{16}) \times 2^{0} = -0.8125.

The exponent becomes negative

Normalise mantissa 00001100, exponent 0001 (8-bit mantissa, 4-bit exponent).

Solution

The mantissa needs to move left until it starts 01: 00001100 → 01100000 is a shift of 3 places.

Exponent: 1−3=−21 - 3 = -2. In 4-bit two's complement: 2=00102 = 0010, invert to 1101, add 1 → 1110.

MantissaExponent
011000001110

Check: before, (116+132)×21=0.1875(\tfrac1{16} + \tfrac1{32}) \times 2^{1} = 0.1875. After, 0.75×2−2=0.18750.75 \times 2^{-2} = 0.1875.

Exam-style: a negative number with a negative exponent

A number is stored with a 10-bit mantissa 1111001100 and a 6-bit exponent 111110, both in two's complement.

(a) Explain why the number is not normalised. (b) Normalise it. (c) Convert the normalised number to denary.

Solution

(a) The first two bits of the mantissa are both 1. A normalised negative mantissa must start 10, so the second bit is a redundant copy of the sign and precision is being wasted.

(b) 1111001100 → 1110011000 → 1100110000 → 1001100000: 3 places left.

Exponent: 111110 =−2= -2; −2−3=−5-2 - 3 = -5. 5=0001015 = 000101, invert 111010, add 1 → 111011.

MantissaExponent
1001100000111011

(c) Mantissa 1.001100000 =−1+18+116=−0.8125= -1 + \tfrac18 + \tfrac1{16} = -0.8125. Value =−0.8125×2−5=−0.8125÷32=−0.025390625= -0.8125 \times 2^{-5} = -0.8125 \div 32 = -0.025390625.

Check against the original: (−1+12+14+18+164+1128)×2−2=−0.1015625÷4=−0.025390625(-1 + \tfrac12 + \tfrac14 + \tfrac18 + \tfrac1{64} + \tfrac1{128}) \times 2^{-2} = -0.1015625 \div 4 = -0.025390625.

When normalisation is impossible

An 8-bit mantissa and 4-bit exponent hold mantissa 00000011 and exponent 1001. Explain why this cannot be normalised in this format.

Solution

The exponent 1001 is −8+1=−7-8 + 1 = -7. To start 01 the mantissa must move left 5 places (00000011 → 01100000), so the exponent would need to become −7−5=−12-7 - 5 = -12.

A 4-bit two's complement exponent can only go down to −8-8, so −12-12 cannot be stored. The number is too small to be represented in normalised form in this format: this is underflow. The system would store it as 0 (or keep it unnormalised, losing precision), so the true value 3128×2−7≈0.000183\tfrac{3}{128} \times 2^{-7} \approx 0.000183 is lost.

Zero and the special cases

  • Zero cannot be normalised: the mantissa 00000000 will never start 01, however far it is shifted. Systems treat a zero mantissa as a special case meaning 0.
  • −1-1 is stored as mantissa 10000000, which starts 10, so it is already normalised.
  • −0.5-0.5 looks as though it should be 11000000 with exponent 0, but that starts 11. Normalised, it is 10000000 (that is, −1-1) with exponent 1111 (−1-1): −1×2−1=−0.5-1 \times 2^{-1} = -0.5. The asymmetry exists because two's complement can hold −1-1 but not +1+1.

Normalising in Python

def twos(bits):
    v = int(bits, 2)
    return v - (1 << len(bits)) if bits[0] == "1" else v

def to_bits(value, width):
    if not -(1 << (width - 1)) <= value < (1 << (width - 1)):
        raise OverflowError(f"{value} does not fit in {width} bits")
    return format(value & ((1 << width) - 1), f"0{width}b")

def normalise(mantissa, exponent):
    if set(mantissa) == {"0"}:
        return mantissa, exponent           # zero is a special case
    exp = twos(exponent)
    while mantissa[0] == mantissa[1]:       # first two bits the same
        mantissa = mantissa[1:] + "0"       # shift left
        exp -= 1                            # compensate
    return mantissa, to_bits(exp, len(exponent))

print(normalise("00011010", "0101"))       # ('01101000', '0011')
print(normalise("11100110", "0010"))       # ('10011000', '0000')
print(normalise("00001100", "0001"))       # ('01100000', '1110')
print(normalise("1111001100", "111110"))   # ('1001100000', '111011')
try:
    print(normalise("00000011", "1001"))
except OverflowError as error:
    print("Cannot normalise:", error)      # -12 does not fit in 4 bits
Watch out
  • Shifting the mantissa left makes it bigger, so the exponent goes down. Students often add instead of subtract.
  • Do not change the sign bit by hand. Shifting a negative mantissa left keeps the leading 1 automatically because the bits being shifted out are all 1s.
  • Fill vacated places on the right with 0.
  • Recalculate the exponent in two's complement; do not just change one bit.
Exam tip
  • "Explain why floating-point numbers are normalised" earns marks for: maximum precision for a given number of bits (no redundant leading bits), a unique representation of each number, and easier comparison/arithmetic.
  • "State how you know this number is normalised" needs both cases: positive starts 01, negative starts 10.
  • For a "normalise this" question, show the shifted mantissa, the number of places, and the exponent calculation in denary before converting to binary.
  • If a question gives a mantissa and asks for the "normalised" form of a denary number, your answer must start 01 or 10, or it scores nothing.
Summary
  • A normalised mantissa has first two bits different: positive 01, negative 10.
  • Normalisation maximises precision and gives a unique representation of every number.
  • To normalise: shift the mantissa left until the first two bits differ, subtracting 1 from the exponent per place.
  • Check the new exponent still fits; if it does not, the number cannot be represented normalised (underflow).
  • Zero cannot be normalised; −0.5-0.5 normalises to mantissa −1-1 with exponent −1-1.

Practice questions

Question
  1. State, with a reason, which of these 8-bit mantissas are normalised: 01011000, 00110000, 10111000, 11010000.
  2. Normalise mantissa 00101100, exponent 0110 (8-bit and 4-bit two's complement), and give the denary value.
  3. Normalise mantissa 11110100, exponent 0011, and show that the value is unchanged.
  4. Normalise mantissa 11101000, exponent 1110.
  5. Normalise the number with 10-bit mantissa 0001011010 and 6-bit exponent 000111, and convert the result to denary.
  6. Give two reasons why floating-point numbers are stored in normalised form.
  7. Explain why mantissa 00110000 with exponent 1000 cannot be normalised in an 8-bit mantissa, 4-bit exponent format.
  8. Show how −0.5-0.5 is stored as a normalised floating-point number with an 8-bit mantissa and a 4-bit exponent, and explain why 11000000 with exponent 0000 is not acceptable.
  9. A computer stores the result of a calculation as 0.00001011012×230.0000101101_2 \times 2^{3} in a system with an 8-bit mantissa and 4-bit exponent. Show the stored value if it is (a) stored without normalising, keeping the exponent as 3, (b) normalised. Give the denary value of each and state the error in each case.
Answers
  1. 01011000: normalised (positive, starts 01). 00110000: not normalised (starts 00). 10111000: normalised (negative, starts 10). 11010000: not normalised (starts 11, second bit copies the sign).

  2. Shift 1 place: 01011000. Exponent 6−1=56 - 1 = 5 → 0101. Value 0.10112×25=0.6875×32=220.1011_2 \times 2^{5} = 0.6875 \times 32 = 22.

  3. 11110100 → 11101000 → 11010000 → 10100000: 3 places. Exponent 3−3=03 - 3 = 0 → 0000. Before: (−1+12+14+18+132)×8=−0.09375×8=−0.75(-1 + \tfrac12 + \tfrac14 + \tfrac18 + \tfrac1{32}) \times 8 = -0.09375 \times 8 = -0.75. After: (−1+14)×1=−0.75(-1 + \tfrac14) \times 1 = -0.75. Unchanged.

  4. 11101000 → 11010000 → 10100000: 2 places. Exponent 1110 =−2= -2; −2−2=−4-2 - 2 = -4 → 1100. Mantissa 10100000, exponent 1100. Value −0.75×2−4=−0.046875-0.75 \times 2^{-4} = -0.046875.

  5. 0001011010 → 0101101000: 2 places. Exponent 7−2=57 - 2 = 5 → 000101. Value 0.1011012×25=(0.5+0.125+0.0625+0.015625)×32=0.703125×32=22.50.101101_2 \times 2^{5} = (0.5 + 0.125 + 0.0625 + 0.015625) \times 32 = 0.703125 \times 32 = 22.5.

  6. Any two of: it gives the maximum precision for the number of bits, because no mantissa bits are wasted on redundant leading 0s or 1s; each number has exactly one representation; it makes comparison and arithmetic of floating-point values consistent and simpler.

  7. The exponent 1000 is −8-8, the most negative value a 4-bit exponent can hold. Normalising needs one left shift (00110000 → 01100000), which would make the exponent −9-9, and that cannot be stored. The value is 38×2−8=0.75×2−9\tfrac38 \times 2^{-8} = 0.75 \times 2^{-9}, which is smaller than the smallest positive normalised number in this format, 0.5×2−8=2−90.5 \times 2^{-8} = 2^{-9}. It is too small to be normalised: underflow.

  8. Mantissa 10000000 (−1-1), exponent 1111 (−1-1): −1×2−1=−0.5-1 \times 2^{-1} = -0.5. 11000000 with exponent 0 has the value −0.5-0.5 but starts 11, so it is not normalised: the second bit is a redundant copy of the sign, and one bit of precision is wasted.

  9. The true value is 0.00001011012×8=451024×8=0.35156250.0000101101_2 \times 8 = \tfrac{45}{1024} \times 8 = 0.3515625.

    (a) Unnormalised, the 8-bit mantissa holds only 0.0000101, so the stored value is 5128×8=0.3125\tfrac{5}{128} \times 8 = 0.3125. Error =0.0390625= 0.0390625.

    (b) Normalised: 0.1011012×2−10.101101_2 \times 2^{-1}, mantissa 01011010, exponent 1111. Stored value 4564×12=0.3515625\tfrac{45}{64} \times \tfrac12 = 0.3515625. Error =0= 0. All the significant bits fit once the leading zeros are removed.

How well do you know this?

Builds on

Where this leads

Console

Search notes, courses and tools, or run an action