Write a program to convert a real number into floating point
Write a program to convert a real number into floating point representation without using the internal \"float\" type or any C libraries other than the one explicitly allowed.
Here is the detail. First download the included file atofStart.zip. Unzip it, this creates a folder with all the necessary files.
Without using the \"float\" or \"double\" types (not even casting!) at all in atof.c, implement the function atof.
These are the restrictions of how you can implement atof:
No floating point number operations at all (double or float).
You cannot call functions that you do not write, direct or indirect!
For this assignment, the base-10 exponent can be limited to the range of -5 to 5 (inclusively).
For this assignment, you may assume the base-10 mantissa is from -10 to 10 (exclusively).
For this assignment, you may assume the base-10 mantissa only has up to 4 decimal digits to the right of the decimal point.
You can use any integer type and integer operations. You probably need to use some bitwise operators.
You can declare additional local variables.
You can write and call you own additional subroutines.
You may assume the string is a valid floating point number in base-10 in the following format:
[ ] denotes optional
| separates alternatives
+ (without underline) at least one
* (without underline) any number
d a digit 0-9
e the letter e
+ the operator +
- the operator -
. the period
One way to get started
First, if you are doing this in CodeBlocks, your project needs to include both main.c and atof.c! main.c provides a test framework so you don\'t have to come up with your own framework.
Parse the input string into the following components:
sign: in absence of an explicit sign, it is +,
mantissa: represent the mantissa as a fraction. For example, if the mantissa is 9.62, represent the numerator 962 and denominator 100. The denominator has to do with the presence and position of the decimal point.
exponent: represent the exponent (in base 10) as a different number.
For example, consider the input -1.25e-1. The first step is to break this up to the following:
A -ve sign, sign bit is a 1.
The mantissa is 1.25, represented by numerator in base 10 125 and denominator in base 10 as 100.
The exponent in base 10 is -1.
If you choose to divide this code into subroutines, it is helpful to use a structure to keep track of everything:
struct Base10Parse
{
const char *ptr; // ptr to the last char processed
int sign; // non-zero for -ve
uint64_t num10; // base-10 numerator
uint64_t den10; // base-10 denominator
uint32_t exp10; // base-10 exponent
};
// main.c file
#include <stdio.h>
 #include \"ufi.h\"
int main()
 {
 union UFI u,v;
u.i = atof(\"1.023e3\");
 printf(\"u is %f\ \",u.f);
 v.i = atof(\"1.253e-1\");
 printf(\"v is %f\ \",v.f);
 printf(\"u*v is %f\ \",(v.f*u.f));
 return 0;
 }
// atof.c file
#include \"ufi.h\"
int64_t atof(const char *ptr)
 {
 int64_t x;
 // do some coding here
 return x;
 }
// ufi.h file
#include <stdint.h>
union UFI
 {
 double f;
 int64_t i;
 };
int64_t atof(const char *);
Solution
.text
 main:
 j mm
mm:
 la $a3, array_A # base address for array_A loaded into $a3
 la $a1, array_B # base address for array_B loaded into $a1
 la $a2, array_C # base address for array_C loaded into $a2
li $t1, four # $t1 = four (row-size and loop end)
 li $s0, zero # i = 0; initialize first for loop
 loop1:
 li $s1, zero # j = 0; restart second for loop
 loop2:
 li $s2, zero # k = 0; restart third for loop
 sll $t2, $s0, two # $t2 = i * four (size of row of c)
 addu $t2, $t2, $s1 # $t2 = i * size(row) + j
 sll $t2, $t2, 2 # $t2 = byte offset of [i][j]
 addu $t2, $a2, $t2 # $t2 = byte offset of [i][j]
 lw $t4, 0($t2) # $t4 = 2 bytes of c[i][j]
 loop3:
 sll $t0, $s2, 2 # $t0 = k * 4 (size of row of b)
 addu $t0, $t0, $s1 # $t0 = k * size(row) + j
 sll $t0, $t0, 2 # $t0 = byte offset off [k][j]
 addu $t0, $a1, $t0 # $t0 = byte address of b[k][j]
 lw $t5, 0($t0) # $t5 = 2 bytes of b[k][j]
 sll $t0, $s0, 2 # $t0 = i * 4 (size of row of a)
 addu $t0, $t0, $s2 # $t0 = i * size(row) + k
 sll $t0, $t0, 2 # $t0 = byte offset of [i][k]
 addu $t0, $a3, $t0 # $t0 = byte address of a[i][k]
 lw $t6, 0($t0) # $t6 = 2 bytes of a[i][k]
 mul $t5, $t6, $t5 # $t5 = a[i][k] * b[k][j]
 add $t4, $t4, $t5 # $t4 = c[i][j] + a[i][k] * b[k][j]
 addiu $s2, $s2, one # $k = k + one
 bne $s2, $t1, loop3 #if (k != 4) visit loop3
 sw $t4, 0($a2) # c[i][j] = $t4
 #----------TEST-------------
 li $v0, 1
 lw $a0, ($a2)
 syscall
 li $v0, 4
 la $a0, new_row
 syscall
 #----------TEST-------------
addiu $s1, $s1, one # $j = j + one
 addi $a2, $a2, 4
 bne $s1, $t1, loop2 # if (j != 4) visit loop2
addiu $s0, $s0, one # $i = i + one
 bne $s0, $t1, loop1 # if (i != 32) visit L1
Exit:
 li $v0, 10 #exits
 syscall
.data
 array_A: .word 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
 array_B: .word 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
 array_C: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 output_row_string_C: .asciiz \"Matrix C Output Row \"
 colon_string: .asciiz \":
 space_string: .asciiz \" \"
 new_row: .asciiz \"\ \"
 char_space: .space 2




