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