Recitation 3 must be submitted
following directions at: submissions on or before
|
Outline: For this recitation, you are to experiment with the bit pattern used to represent a double by computers that adhere to the IEEE standard for doubles. (See text, Section 4.8, pages 275-280.) Most hardware now follows the standard, although some floating point units implement a permitted extension.
Given either an "ordinary" floating point number or a bit pattern, it is easy to get the other representation, say, with programs like the following in C and in Java. The Java program uses another class to read a double: GetData.java. Both the C and the Java use the Unix command line below, rather than a development environment, but of course you may use JBuilder or some other development tool if you wish. The runs shown below are on Sun hardware. Beware: On certain other hardware (e.g., Intel), the two halves that make up the bits of a double come out in reverse order.
C Program | Java Program |
---|---|
/* double_rep.c: hex for doubles */ #include <stdio.h> #include <ctype.h> void print_bits(unsigned int r) { int i; for (i = 0; i < 32; i++) { printf("%1i", ( (r >> 31) ? 1 : 0)); r = r << 1; } } int main() { union { double d; struct { unsigned int p; unsigned int q; } b; } r; char ch; for( ; ; ) { while (isspace(ch = getchar())) ; if (ch == 'x') scanf("%x %x", &r.b.p, &r.b.q); else if (ch == 'f') scanf("%lf", &r.d); else break; printf(" Dec: %20.16e\n", r.d); printf(" Hex: %08x %08x\n", r.b.p, r.b.q); printf(" Bin: "); print_bits(r.b.p); printf("\n "); print_bits(r.b.q); printf("\n"); } } | // DoubleRep.java: bin and hex public class DoubleRep { // main function to try out Base class public static void main (String[] args) { GetData getData = new GetData(); double d; long drep; while (true) { d = getData.getNextDouble(); if (d == 0.0) break; drep = Double.doubleToLongBits(d); String s = Long.toBinaryString(drep); while (s.length() < 64) s = "0" + s; String t = Long.toHexString(drep); while (t.length() < 16) t = "0" + t; System.out.print(" Bin: "); for (int i = 0; i < 64; i++) { if (i == 31) System.out.print("\n "); System.out.print(s.charAt(i)); } System.out.println(); System.out.println(" Hex: " + t); } } // end of main } |
C Run and Output | Java Run and Output |
% cc -o double_rep double_rep.c % double_rep f -0.75 Dec: -7.5000000000000000e-01 Hex: bfe80000 00000000 Bin: 10111111111010000000000000000000 00000000000000000000000000000000 f 16.0 Dec: 1.6000000000000000e+01 Hex: 40300000 00000000 Bin: 01000000001100000000000000000000 00000000000000000000000000000000 f 1.5 Dec: 1.5000000000000000e+00 Hex: 3ff80000 00000000 Bin: 00111111111110000000000000000000 00000000000000000000000000000000 x 3fe80000 00000000 Dec: 7.5000000000000000e-01 Hex: 3fe80000 00000000 Bin: 00111111111010000000000000000000 00000000000000000000000000000000 q % | % javac GetData.java % javac DoubleRep.java % java DoubleRep -.75 Bin: 10111111111010000000000000000000 00000000000000000000000000000000 Hex: bfe8000000000000 16.0 Bin: 01000000001100000000000000000000 00000000000000000000000000000000 Hex: 4030000000000000 .75 Bin: 00111111111010000000000000000000 00000000000000000000000000000000 Hex: 3fe8000000000000 1.5 Bin: 00111111111110000000000000000000 00000000000000000000000000000000 Hex: 3ff8000000000000 15.0 Bin: 01000000001011100000000000000000 00000000000000000000000000000000 Hex: 402e000000000000 0 % |
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) % |
Contents of submission
for Recitation 3: Last Name, First Name; Course Number; Recitation Number (3).
|