Computer
Organization and Design
(Textbook. Click for information.)
 CS 2733/2731
 Computer Organization II
 Fall 2004

 Fancy double in C


An Elaborate C Program: Here is a more interesting program that tears an input double apart and assembles the individual pieces as in the book:

C Program

four06% cat double_rep2.c
/* double_rep2.c: input a double, tear it into its component, reassemble.
 *   See Patterson & Hennessy, Comp. Org. & Design, pages 278-279
 *   for notation.
 *   Here Result = (-1)^Sign x (1 + Significand) x 2^(Exponent - Bias)
 */
#include <stdio.h>
#include <ctype.h>
/* this union allows one to extract bits from a double */
union double_tag {
   double d;
   struct {
      unsigned int p;
      unsigned int q;
   } b;
};
int main() {
   union double_tag r;                      /* holds the input */
   unsigned int Sign_mask     = 0xA0000000; /* to extract Sign */
   unsigned int Exponent_mask = 0x7FF00000; /* to extract Exponent */
   unsigned int Signific_mask = 0x000FFFFF; /* to extract Signficand */
   unsigned int Sign;                       /* Sign */
   unsigned int Exponent;                   /* Exponent */
   unsigned int Signific;                   /* Significand, an int */
   double Significand;                      /* Significand */
   unsigned int Bias = 1023;                /* Bias */
   double Result;                           /* result of reassembling */
   int BiasedExponent;                      /* Biased Exponent = Exponent - bias */
   int i;
   for( ; ; ) {
      scanf("%lf", &r.d);
      Sign = (r.b.p & Sign_mask) >> 31;
      Exponent = (r.b.p & Exponent_mask) >> 20;
      Signific  = r.b.p & Signific_mask;
      Significand = ( (double) Signific + r.b.q / 4294967295.0) / 1048576.0;
      /* Note: the extra r.b.q / 4294967295.0 adds in the lower 32 bits. */
      printf("(-1)^Sign x (1 + Significand) x 2^(Exponent - Bias) = Result\n");
      Result = (Sign ? -1.0 : 1.0) * (1 + Significand);
      BiasedExponent = Exponent - Bias;
      if (BiasedExponent >= 0) {
          for (i = 0; i < BiasedExponent; i++)
             Result = Result * 2.0;
      }
      else {
          for (i = 0; i < -BiasedExponent; i++)
             Result = Result / 2.0;
      }
      printf("(-1)^%1i    x (1 + %11.9f) x 2^(%4i     - %4i) = %20.16f\n",
          Sign, Significand, Exponent, Bias, Result);
   }
}
C Run and Output
% cc -o double_rep2 double_rep2.c
% double_rep2
-.75
 (-1)^Sign x (1 + Significand) x 2^(Exponent - Bias) = Result
 (-1)^1    x (1 + 0.500000000) x 2^(1022     - 1023) = -0.7500000000000000
16.0
 (-1)^Sign x (1 + Significand) x 2^(Exponent - Bias) = Result
 (-1)^0    x (1 + 0.000000000) x 2^(1027     - 1023) = 16.0000000000000000
1.5
 (-1)^Sign x (1 + Significand) x 2^(Exponent - Bias) = Result
 (-1)^0    x (1 + 0.500000000) x 2^(1023     - 1023) =  1.5000000000000000
15.0
 (-1)^Sign x (1 + Significand) x 2^(Exponent - Bias) = Result
 (-1)^0    x (1 + 0.875000000) x 2^(1026     - 1023) = 15.0000000000000000
^C  (ctrl-C)
%


Revision date: 2004-11-20. (Please use ISO 8601, the International Standard.)