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).
|