Floating point 规范化MIPS中的有效位

Floating point 规范化MIPS中的有效位,floating-point,mips,normalization,Floating Point,Mips,Normalization,我试图弄清楚在进行浮点加法时如何规范化MIPS中的有效位 假设你有0.001*2^-1。在本例中,要规范化,必须将有效位向左移动3,并将指数减小3 我如何确定最高有效位回到标准化位置(在我之前的例子中,我如何知道我在第三次移位后停止移位) 更新:这是我目前使用的代码。给定两个输入(浮点数),程序应该进行半精度浮点加法,这就是我将单精度转换为半精度的原因。输出应该只是两个浮点数的总和 我认为问题在于正常化 .data ask_user_a: .asciiz "Enter a decima

我试图弄清楚在进行浮点加法时如何规范化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.
.data
询问用户:.asciiz“输入十进制数(a)”
询问用户:。asciiz“输入十进制数(b)”
总和:.asciiz“a+b=”
错误超出范围:。asciiz“错误:您输入的数字超出范围!”
新行:.asciiz“\n”
.文本
主要内容:
#向用户请求输入a
la$a0,ask_user_a#将ask_user_a的addr加载到$a0中。
li$v0,4#4是打印字符串系统调用。
系统调用#执行系统调用。
#将输入a放入$s0
li$v0,6#6用于获取浮点数
系统调用#执行系统调用
mfc1$s0,$f0#将浮点数移动到$s0
##要求用户输入b
la$a0,ask_user_b#将ask_user_b的addr加载到$a0中。
li$v0,4#4是打印字符串系统调用。
系统调用#执行系统调用。
#将输入b放入$s1
li$v0,6#6用于获取浮点数
系统调用#执行系统调用
mfc1$s1,$f0#将浮点数移动到$s1
#为一个项目提取部分
srl$t0,$s0,31#$t0=符号位A
sll$t1、$s0、1
srl$t1,$t1,24
sub$t1,$t1,127#t1=指数位A
sll$t2、$s0、9
srl$t2,$t2,9#t2=尾数
srl$t2,$t2,13#截断尾数
ori$t2,$t2,0x800000
srl$t2、$t2、12
#为B提取部件
srl$t5,$s1,31#$t5=符号位B
sll$t6、$s1、1
srl$t6、$t6、24
sub$t6、$t6、127#t6=指数位B
sll$t7、$s1、9
srl$t7,$t7,9#t7=尾数B
srl$t7$t7,13#截断尾数
ori$t7$t7,0x800000
srl$t7、$t7、12

##检查指数A是否大于16和16,此代码使用浮点输入数字的两个符号来选择用于规范化有效位的代码。如果符号相同(t0等于t5),则它将尝试通过右移进行规范化,直到设置结果有效位的位12(0x1000)。如果符号不同,它将尝试通过向左移位进行规范化,直到设置位12

这没有任何意义

要规范化有效位,如果它太大而无法容纳所需的位数,则将其右移(并应根据需要对其进行四舍五入)。如果它太小,无法达到所需的位,则将其向左移动。(此时可能需要使用正有效位。如果对有效位执行的算术结果为负数,则确定有效位是否具有所需的位集会变得复杂。)


您可以考虑用C语言或熟悉和舒适的语言进行操作和调试,然后转换成程序集。

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

这没有任何意义

要规范化有效位,如果它太大而无法容纳所需的位数,则将其右移(并应根据需要对其进行四舍五入)。如果它太小,无法达到所需的位,则将其向左移动。(此时可能需要使用正有效位。如果对有效位执行的算术结果为负数,则确定有效位是否具有所需的位集会变得复杂。)


您可以考虑用C语言或熟悉和舒适的语言进行操作和调试,然后转换为程序集。

只要顶部位为0,就可以移动。作为一个人,你可以看到这是3倍。在代码中,它稍微复杂一些,但不太复杂。现在我将有效位与0x1000进行AND运算,如果anded值=0,则我将移位。这似乎不管用,有什么想法吗?@richard008:这是一种家庭作业吗?因为否则,对于单精度/双精度,应分别使用浮点加法指令
add.s
add.d
,以及你期望或希望它产生什么。@gusbo是的,这是我的一个课程的最后一个项目。我还更新了这个问题,以显示我当前让您移位的代码,只要顶部位为0。作为一个人,你可以看到这是3倍。在代码中,它稍微复杂一些,但不太复杂。现在我将有效位与0x1000进行AND运算,如果anded值=0,则我将移位。这似乎不管用,有什么想法吗?@richard008:这是一种家庭作业吗?因为否则,对于单精度/双精度,应分别使用浮点加法指令
add.s
add.d
,以及你期望或希望它产生什么。@gusbo是的,这是我的一个课程的最后一个项目。我还更新了问题,以显示我目前拥有的代码