规范化MIPS中的有效数

时间:2013-04-26 03:12:25

标签: floating-point mips normalization

我正在试图弄清楚如何在进行浮点加法时对MIPS中的有效数进行标准化。

假设你有0.001 * 2 ^ -1。在这种情况下,为了规范化,你必须将有效数字移位3并且将指数递减3.

我如何确定最重要的位回到标准化位置(在我之前的情况下,我怎么知道我在第三班后停止换档)?


更新:这是我目前使用的代码。给定两个输入(浮点数),程序应该进行半精度浮点加法,这就是我从单精度转换为半精度的原因。输出应该只是两个浮点数的总和

我认为问题在于正常化。

.data
ask_user_a:     .asciiz "Enter a decimal number (a): "
ask_user_b:     .asciiz "Enter a decimal number (b): "
sum:            .asciiz "a+b = "
error_out_of_range: .asciiz "Error: A number you entered is out of range! "
new_line:       .asciiz "\n"


.text
main:
#Ask user for the input a
la $a0, ask_user_a      # load the addr of ask_user_a into $a0.
li $v0, 4           # 4 is the print_string syscall.
syscall             # do the syscall.

#put input a into $s0
li $v0, 6           #6 for getting floating point numbers
syscall             # do the syscall
mfc1  $s0, $f0          #move floating point number to $s0

## ask user for the input b
la $a0, ask_user_b      # load the addr of ask_user_b into $a0.
li $v0, 4           # 4 is the print_string syscall.
syscall             # do the syscall.

#put input b into $s1
li $v0, 6           #6 for getting floating point numbers
syscall             # do the syscall
mfc1  $s1, $f0          #move floating point number to $s1

#extract parts for A
srl $t0, $s0, 31        #$t0 = Sign Bit A
sll $t1, $s0, 1
srl $t1, $t1, 24        
sub $t1, $t1, 127       #t1 = Exponent Bit A    
sll $t2, $s0, 9
srl $t2, $t2, 9         #t2 = Mantissa A
srl $t2, $t2, 13        #Truncate Mantissa
ori $t2, $t2, 0x800000
srl $t2, $t2, 12

#extract parts for B
srl $t5, $s1, 31        #$t5 = Sign Bit B
sll $t6, $s1, 1
srl $t6, $t6, 24        
sub $t6, $t6, 127       #t6 = Exponent Bit B
sll $t7, $s1, 9
srl $t7, $t7, 9         #t7 = Mantissa B
srl $t7, $t7, 13        #Truncate Mantissa
ori $t7, $t7, 0x800000
srl $t7, $t7, 12

##Check that exponent A is >16 and <-16, jump to error otherwise
blt $t1, -16, oor_error
bgt $t1, 16, oor_error

##Check that exponent B is >16 and <-16, jump to error otherwise
blt $t6, -16, oor_error
bgt $t6, 16, oor_error

j no_oor_error

#Throw error
oor_error:  
la $a0, error_out_of_range  # load the addr of ask_user_a into $a0.
li $v0, 4           # 4 is the print_string syscall.
syscall             # do the syscall.
j exit      

#There was no out of range error
no_oor_error:

#compare exponents
beq $t6, $t1, exponents_match
bgt $t6, $t1 expBgtexpA
sub $t8, $t6, $t1
srlv $t7, $t7, $t8
move $t6, $t1
j exponents_match
expBgtexpA:
sub $t8, $t1, $t6
srlv $t2, $t2, $t8
move $t1, $t6

exponents_match:
#If the signs are the same, add mants
#If the signs are diff, subtract mants
bne $t0, $t5, different_signs
add $t9, $t2, $t7
j significands_added
different_signs:
sub $t9, $t2, $t7


significands_added:
#normalize

#determine size
bne $t0, $t5, normalize_different_sign

normalize_same_sign:
andi $t8, $t9, 0x1000
beq $t8, $zero, done_normalize
srl $t9, $t9, 1
addi $t1, $t1, 1
j normalize_same_sign

normalize_different_sign:
andi $t8, $t9, 0x1000
beq $t8, $zero, done_normalize
sll $t9, $t9, 1
subi $t1, $t1, 1
j normalize_different_sign

done_normalize: 
#Check for overflow

##Convert back to float
sll $t0, $t0, 31        ##move sign to 32nd bit
addi $t1, $t1, 127      ##Add bias
sll $t1, $t1, 23        #move exponent to bits 24-31
sll $t9, $t9, 11        #move over mant
andi $t9, $t9, 0x3FFFFF
sll $t9, $t9, 1 

or $s2, $t0, $t1
or $s2, $s2, $t9

#Print the float
mtc1 $s2, $f12
li  $v0,    2   
syscall

exit:
#Exit Program
li $v0, 10          # syscall code 10 is for exit.
syscall             # make the syscall.

1 个答案:

答案 0 :(得分:1)

此代码使用浮点输入数字的两个符号来选择用于规范有效数字的代码。如果符号相同(t0等于t5),则尝试通过向右移位进行归一化,直到设置结果有效数的第12位(0x1000)。如果符号不同,它会尝试通过向左移动进行标准化,直到设置第12位。

这没有任何意义。

要对有效数进行标准化,如果它太大而无法容纳所需的位数,则将其向右移动(并且它也应根据需要进行舍入)。如果它太小而没有达到所需的位,则向左移动。 (在这一点上,人们可能希望使用正有效数。如果对有效数字执行的算术结果是负数,则确定有效数是否具有所需的位集会变得复杂。)

您可以考虑使用C语言或您熟悉的语言来实现该操作,并且可以轻松地进行调试,然后转换为汇编。