Для случая, когда делитель> дивиденд, вычисленная мантисса дает неверный результат для последних 4-5 младших разрядов.
Я пытаюсь разделить значения и мантиссу двух чисел с плавающей точкой IEEE-754. Я использовал этот алгоритм деления
Когда делитель> дивиденд, мантисса нормализуется, но все еще неверна для последних 4-5 бит.
DivisionAlgorithm: # Делит Мантиссу Дивиденда (в $ a0) на Мантиссу Дивизора (в $ a1) за 25 Итераций #
# Возвращает частное значение в $ v0 #
addi $sp, $sp, -12 #Decrement in $sp (Stack Pointer)
sw $s0, 0($sp) #Pushing $s0 into Stack
sw $ra, 4($sp) #Pushing $ra into Stack (Function Call Exists)
sw $s1,8($sp) #Pushing $s1 into stack
move $t0, $a0 #$t0 = Mantissa of Dividend/Remainder
move $t1, $a1 #$t1 = Mantissa of Divisor
add $s0, $0, $0 #$s0 = Initialization
add $v1, $0, $0 #$v1 = 0 (Displacement of Decimal Point Initialized)
addi $s1,$0,1 #$s1 = 1 (initialize loop variable to 1)
add $t3,$0,33
loop:
beq $t1, $0, check #If Divisor = 0, Branch to check
sub $t0, $t0, $t1 #Dividend = Dividend - Divisor
sll $s0, $s0, 1 #Quotient Register Shifted Left by 1-bit
slt $t2, $t0, $0
bne $t2, $0, else #If Dividend < 0, Branch to else
addi $s0, $s0, 1 #Setting Quotient LSb to 1
j out
else: add $t0, $t0, $t1 #Restoring Dividend Original Value
out: srl $t1, $t1, 1 #Divisor Register Shifted Right by 1-bit
j loop
check: slt $t2, $a0, $a1 #If Dividend < Divisor, Call Function 'Normalization'
beq $t2, $0, exit #If Dividend > Divisor, Branch to exit
move $a0, $s0 #$a0 = Quotient
jal Normalization #Function Call
j return
exit: move $v0, $s0 #$v0 = Calculated Mantissa
return: lw $ra, 4($sp) #Restoring $ra
lw $s0, 0($sp) #Restoring $s0
lw $s1, 8($sp) #restoring $s1
addi $sp, $sp, 8 #Increment in $sp (Stack Pointer)
jr $ra #Return
Нормализация: # Нормализует Мантиссу (в $ a0) и считает десятичные разряды, сдвинутые на десятичную точку #
#Returns:
# i) $ v0 = нормализованная мантисса #
# ii) $ v1 = Количество десятичных знаков #
lui $t0, 0x40 #$t0 = 0x40 (1 at 23rd-bit)
addi $t2, $0, 1 #$t2 = 1 (Initialization)
loop2: and $t1, $a0, $t0 #Extracting 23rd-bit of Mantissa
bne $t1, $0, else2 #If 23rd-bit = 1; Branch to else2
addi $t2, $t2, 1 #Increment in Count of Decimal Places Moved
sll $a0, $a0, 1 #Mantissa Shifted Left (To Extract Next Bit)
j loop2
else2: sll $a0, $a0, 1 #Setting 24th-bit = 1 (Implied)
move $v0, $a0 #$v0 = Normalized Mantissa
move $v1, $t2 #$v1 = Displacement of Decimal Point
jr $ra #Return
Например, я ожидаю, что выход 2.75 / 6.355 будет 00111110110111011000111011001110, но фактический вывод будет 00111110110111011000111011010110.