|
CS 2733/2731 Computer Organization II Fall 2004 Recitation 14 Floating Point Week 14: Nov 22-24 Due (on time): 2004-12-01 23:59:59 Due (late): 2004-12-05 23:59:59 |
Recitation 14 must be submitted
following directions at: submissions on or before
|
Outline: This recitation has two parts:
| 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
%
|
The first is a simple calculation of 355.0/113.0 as a double. These numbers take up 8 bytes, and are stored in special floating point registers: $f0 through $f31, but doubles are only stored in an even numbered floating point register, along with the following odd-numbered register. With $v0 = 3, syscall will print the double value in $f12 (and $f13). Many MIPS instructions have an analog for doubles with .d tacked onto the end.
| MIPS, PI = (approx) 355/113 | spim output |
|---|---|
# calculate pi = 355.0/113.0
.globl main
main: addu $s7, $zero, $ra
la $a0, Nums
l.d $f2, 0($a0) $ load double
l.d $f4, 8($a0) $ load double
div.d $f6, $f2, $f4 $ divide double
li $v0, 3
mov.d $f12, $f6 $ move double
syscall
addu $ra, $zero, $s7
jr $ra
.data
.align 3
Nums: .double 355., 113.
| $ spim -file pi.s 3.14159292035398252 |
The next program below uses an approximation algorithm to calculate pi, but the looping is just an integer loop like the ones you are used to. Notice that MIPS has a sqrt.d hardware instruction to take the square root.
| MIPS: Pi approximation | C equivalent and spim output |
|---|---|
.globl main
main: addu $s7, $zero, $ra
la $a0, Nums
l.d $f2, 0($a0) # p = 2.0
l.d $f4, 8($a0) # b = 0.0
mov.d $f6, $f2 # 2.0
li $t0, 0
li $t1, 26
Loop: add.d $f8, $f4, $f6 # $f8 = 2+b
sqrt.d $f4, $f8 # b = sqrt($f8)
div.d $f10, $f6, $f4 # t = 2/b
mul.d $f2, $f2, $f10
addi $t0, $t0, 1
li $v0, 3
mov.d $f12, $f2
syscall # print p
li $v0, 4
la $a0, Newl
syscall # print Newl
bne $t0, $t1, Loop
li $v0, 3
mov.d $f12, $f2
syscall # print p
li $v0, 4
la $a0, Newl
syscall # print Newl
addu $ra, $zero, $s7
jr $ra
.data
.align 3
Nums: .double 2., 0.
Newl: .asciiz "\n"
| $ cat pi2.c
#include <stdio.h>
#include <math.h>
int main() {
double p = 2; /* final product */
double b = 0; /* each denom */
double t; /* term */
int i;
for (i = 0; i < 24; i++) {
b = sqrt(2 + b);
t = 2.0/b;
p = p*t;
printf("%20.15f\n", p);
}
printf("%20.15f\n", p);
}
|
The third program below creates a loop that depends on the results of the floating point calculations. These use MIPS floating point Condition Codes. There are 8 binary Condition Codes, but we are only using Condition Code number 0 here (the default). I couldn't find out how to use the other numbers.
The instruction
sets the Condition Code 0 to true (1) in case the first argument is less than the second, and sets it to false (0) otherwise. The instruction
branches to Loop in case the default condition code 0 was set to false, and doesn't branch otherwise. Automatically setting a condition code whose value can be used by a later instruction is more like a real assembly language, although in MIPS it seems to be in a rudimentary form.
| MIPS: simple branch example | C equivalent and spim output |
|---|---|
main: addu $s7, $zero, $ra
la $a0, Nums
l.d $f2, 0($a0) # n = 2.0
l.d $f4, 8($a0) # d = 37.0
l.d $f6, 16($a0) # e = 1.0e-15
Loop: div.d $f2, $f2, $f4 # n = n/37
li $v0, 3
mov.d $f12, $f2
syscall # print n
li $v0, 4
la $a0, Newl
syscall
c.lt.d $f2, $f6 # is n < e ?
bc1f Loop # branch back if not
li $v0, 3
mov.d $f12, $f2
syscall # print n
li $v0, 4
la $a0, Newl
syscall
addu $s7, $zero, $ra
jr $ra
.data
.align 3
Nums: .double 2., 37., 1.0e-15
.align 2
Newl: .asciiz "\n"
| $ cat branch.c
#include <stdio.h>
#include <math.h>
int main() {
double n = 2.0;
double d = 37.0;
double e = 1.0e-15;
while (1) {
n = n/d;
printf("%20.15e\n", n);
if (n < e) break;
}
printf(" %20.15e\n", n);
}
|
|
Contents of submission
for Recitation 14: Last Name, First Name; Course Number; Recitation Number (14).
|