To make things more concrete let's look at a typical floating-point
 representation for a REAL (SINGLE PRECISION) - the single-precision 
 unextended IEEE (ANSI/IEEE Std 754-1985) that became a de facto 
 standard on workstations. The '*4' is a non-standard notation that 
 says that 4 bytes are allocated for the representation. 

 A schematic description of the representation follows, the 4 bytes 
 contain 32 bits that are partitioned into 3 parts (the letter 'S' 
 in the left part is short for 'Sign')

  |S|  exp   |       fraction        |
  +-+--------+-----------------------+              Direction of 
   ^                                ^     <---  increasing addresses
 Bit31                             Bit0        (See discussion below)

 A formula that gives the value of this float is:

   Value = (-1)**S  X  1.fffffffffffffffffffffff  X  2**(exp - 127)

 The most significant bit (MSB) is the sign bit, it is 0 for a positive 
 number and 1 for a negative number.

 The next 8 bits describe the exponent which is BIASED by 127 (see the 
 formula above), so the range of values is [-127, 128]

 The remaining 23 bits are taken as the binary digits of a binary fraction 
 that has a "whole part" = 1 (see the formula above), this condition is just 
 the normalization condition. 

 An IEEE normalized mantissa always has a leading '1' bit, so it is really 
 redundant and can be always omitted (an old 'trick' attributed to David 
 Goldberg), it 'saves' one bit that can be used to improve the precision.

 The following program may help you examine the structure of REAL on
 your machine, it is based on the plausible assumption that integers are 
 represented in two's complement format. 

 Of course we could use the Z edit descriptor, but it is not standard 
 FORTRAN 77, and so may not be implemented by all compilers.

C     ------------------------------------------------------------------
     *              X
C     ------------------------------------------------------------------
      WRITE(*,*) ' Enter a REAL number: '
      READ(*,*) X
C     ------------------------------------------------------------------

C     ------------------------------------------------------------------
     *              I,
     *              INT
C     ------------------------------------------------------------------
     *              B*32
C     ------------------------------------------------------------------
      IF (INT .GE. 0) THEN
        B(1:1) = '0'
        DO I = 32, 2, -1
          IF (MOD(INT,2) .EQ. 0) THEN
            B(I:I) = '0'
            B(I:I) = '1'
          INT = INT / 2
        B(1:1) = '1'
        INT = ABS(INT + 1)
        DO I = 32, 2, -1
          IF (MOD(INT,2) .EQ. 0) THEN
            B(I:I) = '1'
            B(I:I) = '0'
          INT = INT / 2
C     ------------------------------------------------------------------
      WRITE(*,*) '   ', B(1:8),' ', B(9:16),' ', B(17:24),' ', B(25:32)
      WRITE(*,*) '   ........ ........ ........ ........ '
      WRITE(*,*) '   21098765 43210987 65432109 87654321 '
      WRITE(*,*) '     3          2          1           '
      WRITE(*,*) ' '
C     ------------------------------------------------------------------

 Special numbers
 Using normalized mantissas raises a little problem, how to represent 
 zero when the mantissa is not allowed to have zero value? 
 The IEEE solution is to represent the number zero by a zero fraction 
 and exponent, but no condition is imposed on the SIGN BIT, so we 
 have two 'zeros' +0 and -0!

 Remember that the exponent is biased by 127, so that a zero exponent 
 really means that the binary fraction is 'multiplied' by (2 ** (-127)),
 in other words, the minimal exponent is reserved to represent zero.

 There is also an internal representation for 'INFINITY', it consists
 of the maximal exponent = 255 (128 after debiasing) and all fraction 
 bits = 0. So we have also two 'infinities' one positive and one negative.

 An even stranger phenomenon is the class of bit patterns called NaNs, 
 a NaN has exponent = 255 (128 after debiasing) and fraction bits
 which are not all 0. NaN is short for 'Not A Number'.

 The special numbers (except zero) were invented in order to implement 
 NON-STOP ARITHMETIC, instead of aborting the program in the case an 
 intermediary calculation gives a bad result, the result is replaced 
 by the appropriate special number and computation continues.

 IEEE arithmetic implements an extension of the real numbers system, 
 the quantities +INFINITY, -INFINITY and the NaNs are added to the 
 real numbers, and arithmetic operations involving them are defined 
 in a plausible way. Many users find this extension confusing and 
 not very useful.

 The 'representation density' of IEEE/REAL*4
 What is the spacing between two consecutive floating-point numbers?

 Positive FPN are the product of a 'normalized' binary fraction with
 23 binary digits, and  (2 ** e), where  e  is in [-126,127].

 Remember that the exponents -127 and +128 are reserved to represent 
 zero and infinity respectively. 

 The 'normal' FPNs can be partitioned into 254 disjoint sets, one for 
 each possible exponent, each set containing  (2 ** 23)  numbers, one
 for each possible binary fraction of length 32.

 The spacing between consecutive numbers belonging to the same set,
 is the same, and equals  (2 ** (-23)) * (2 ** e) = 2 ** (e -32).

 It is clear that the spacing increases when e (and the magnitude
 of the number) increases.

 The minimal positive FPN is  (+1.0) * (2 ** (-126)) = 2 ** (-126),
 the spacing at that region is  (2 ** (-126 - 32))   = 2 ** (-158).

 We see that the minimal positive FPN is MUCH LARGER than the 
 local spacing.

 The number space of IEEE/REAL*4
 If we will translate the binary data from previous sections to 
 decimal, we will find the range of numbers that can be represented 
 by the IEEE REAL*4 is:

        (-3.4 X 10**+38, +3.4 X 10**+38)

 Because the minimal FPN is so much larger than the nearby spacing, 
 it is more instructive to look at that range as the union of three 
 discrete segments:

        (-3.4 X 10**+38, -1.2 X 10**-38)


        (+1.2 X 10**-38, +3.4 X 10**+38)

 In this floating-point representation we have a finite number of numbers 
 filling the three ranges, two of them with variable 'density'. 

  |     SUMMARY                                                         |
  |     =======                                                         |
  |     1) IEEE/REAL*4 = 1 Sign bit, 8 exponent bits, 23 mantissa bits  |
  |     2) There are all kinds of 'strange numbers'                     |
  |     3) The number space is discrete, made of three parts, and has   |
  |         maximal 'density' near zero                                 |

Return to contents page