Hi Daniweb,
I am working on an assignment that is aimed to help us understand floating points. The current task is to take a number as input, example 3.5, or 2.25 etc and output it as a binary decimal, ex 11.100000000, 10.0100000000.
To do this, I am taking the whole number and floating point seperately, converting them seperately and storing them seperately. The whole number part is working ok, however an issue is coming with the decimal part:
I am inputting it as a string, so .25 would be inputted as "25". I then convert it to binary by:
1) loading the first character into a register, say, $t0
2) subtracting 48 from it to get the decimal equavalent, so '2' becomes 2
3) loading the next character into, say, $t1
4) if the next character is either $zero (null character) or 10 (newline character), skip to step 10
5) $t3 contains 10, and this step it is multiplied by 10
6) repeat step 2 on $t1
7) multiplying the number in $t0 by 10, so $t0 becomes 2x10 = 20
8) adding $t0 to $t1 so it becomes 25
9) go back to step 3
10)multiply the number in t0 by 2
11)if the result is greater than the number in $t3 (in this case 50<100), store a 1 in memory. Else, store a 0
I also have a counter to enforce a maximum number of decimal places in binary
The problem that is arising is that when the QtSpim simulator comes to step 4, and is supposed to be loading the newline character, the number that comes in the register is 49. Hence it doesnt break out of the loop when its supposed to.
Can someone tell me whats going on? heres my code for input and conversion of the floating part of the numbers:
INPUT:
la $s1, firstdecfl
addi $v0, $zero, 8
add $a0, $zero, $s1
addi $a1, $zero, 4
syscall #input decimal part, take no more than 3 digits, store in firstdec
CONVERSION:
addi $t6, $zero, 20 #max num of dec places
#first we need to merge the character array into a number
la $t5, newline
lb $t5, 0($t5) #t5 contains newline
la $s3, firstbinfl #$s3 points to character array that will hold binary notation floating point
la $s1, firstdecfl #s1 points to char array that holds decimal notation floating point
lb $t0, 0($s1) #bring the nextfloat character into register
addi $t0, $t0, -48 #convert it to number
addi $t3, $zero, 10 #to compare if decimal values have exceeded two places, and also used to check for newline(=10) character, as well as multiply while merging
addi $s1, $s1, 1 #move to next char
addi $t4, $zero, 10 #will be 10^n where n is number of decimal places, or digits in firstdecl. Will be used to divide the dec floating point
concat:
lb $t2, 0($s1)
beq $t2, $t5 firstflconv
beq $t2, $zero, firstflconv
mult $t3, $t4
mflo $t4
addi $t2, $t2, -48 #else repeat for the one after that
mult $t0, $t3 #multiply the first digit by 10
mflo $t1
add $t1, $t1, $t2 #and add the second digit to it, so '2', '5' will become 2*10+5 = 25, store in t0
addi $s1, $s1, 1
add $t0, $zero, $t1
j concat
firstflconv:
beq $t6, $zero, printdot
sll $t0, $t0, 1 #multiply by two
bge $t0, $t4, storeone
storezero:
addi $t6, $t6, -1
addi $t5, $zero, 48
sb $t5, 0($s3) #store '0'
addi $s3, $s3, 1 #move pointer to next byte
blt $t0, $t4, firstflconv
storeone:
addi $t6, $t6, -1
addi $t5, $zero, 49
sb $t5, 0($s3) #store '1'
addi $s3, $s3, 1
div $t0, $t4
mfhi $t0 #restandardize the comparison numbers
blt $t0, $t4, firstflconv
Print:
printdot:
addi $t6, $zero, 20 #max dec places again
la $s3, firstbinfl
addi $a0, $zero, 46
addi $v0, $zero, 11
syscall
printdecs:
addi $v0, $zero, 11
lb $a0, 0($s3)
syscall
addi $s3, $s3, 1
addi $t6, $t6, -1 #reduce counter
bne $t6, $zero, printdecs