Floating point 浮点错误

Floating point 浮点错误,floating-point,mips,Floating Point,Mips,我正试图找出我下面的代码到底出了什么问题 快速背景:这个程序的想法是根据一名球员的单打、双打、三打、本垒打和出局次数来计算击球平均数和击球百分比。我针对代码运行的一个测试用例的值是天文数字,每当我尝试对它们进行任何类型的加法时,代码都会失败。我意识到我需要使用双点浮点(特别是在添加输出和命中时,它应该以31500032号结束,但却存储26207920),但我根本不知道如何使用我的代码来实现这一点。有什么建议吗 # test with three batters, both average and

我正试图找出我下面的代码到底出了什么问题

快速背景:这个程序的想法是根据一名球员的单打、双打、三打、本垒打和出局次数来计算击球平均数和击球百分比。我针对代码运行的一个测试用例的值是天文数字,每当我尝试对它们进行任何类型的加法时,代码都会失败。我意识到我需要使用双点浮点(特别是在添加输出和命中时,它应该以31500032号结束,但却存储26207920),但我根本不知道如何使用我的代码来实现这一点。有什么建议吗

# test with three batters, both average and slugging percentage
# First batter has no hits, but does have outs
# Second batter has hits and outs, with realistic values
# Third hitter has large values for some of the hits and for the
# outs. This means the hits and outs *have* to be converted from int's
# to float's in order to get the right answer.

.data

mainNumBatters:
   .word 3

mainBatter1:
   .word 0, 0, 0, 15, 0   # player with no atBats
mainBatter2:
   .word 101  # singles
   .word  22  # doubles
   .word   4  # triples
   .word 423  # outs
   .word  10  # home runs
mainBatter3:
   .word 8000000  # singles
   .word  22  # doubles
   .word 500000    # triples
   .word 23000000  # outs
   .word  10  # home runs

mainNewline:
         .asciiz  "\n"
mainBatterNumber:
         .asciiz  "Batter number: "
mainBattingAverage:
         .asciiz  "Batting average: "
mainSluggingPercentage:
         .asciiz  "Slugging percentage: "

.text

main:
         # Function prologue -- even main has one
         subu  $sp, $sp, 24      # allocate stack space -- default of 24 here
         sw    $fp, 0($sp)       # save frame pointer of caller
         sw    $ra, 4($sp)       # save return address
         addiu $fp, $sp, 20      # setup frame pointer of main

         # for (i = 0; i < mainNumBatters; i++)
         #    compute batting average
         #    compute slugging average

         la    $s0, mainNumBatters
         lw    $s7, 0($s0)       # $s7 = number of batters
         addi  $s6, $zero, 0     # $s6 = i = 0
         la    $s0, mainBatter1  # $s0 = addr of current batter's stats

mainLoopBegin:         
         slt   $t0, $s6, $s7     # $t0 = i < number of batters
         beq   $t0, $zero, mainDone

         la    $a0, mainBatterNumber
         addi  $v0, $zero, 4
         syscall
         addi  $a0, $s6, 1
         addi  $v0, $zero, 1
         syscall
         la    $a0, mainNewline
         addi  $v0, $zero, 4
         syscall

         lw    $a1,  0($s0)      # $a1 = singles
         lw    $a2,  4($s0)      # $a2 = doubles
         lw    $a3,  8($s0)      # $a3 = triples
         lw    $s5, 16($s0)      # $s5 = home runs
         lw    $s4, 12($s0)      # $s4 = outs

         sw    $s4, -4($sp)      # put outs at top of average's stack
         sw    $s5, -8($sp)      # put homeruns 2nd fm top of average's stack
         addi  $a0, $zero, 1     # $a0 = 1 = compute batting average
         jal   average

         # Print the average
         mtc1  $v0, $f12         # get result fm $v0 before we print string
         la    $a0, mainBattingAverage
         addi  $v0, $zero, 4
         syscall
         addi  $v0, $zero, 2     # print the average
         syscall
         la    $a0, mainNewline
         addi  $v0, $zero, 4
         syscall
         syscall

         # do it again for the slugging percentage
         lw    $a1,  0($s0)      # $a1 = singles
         lw    $a2,  4($s0)      # $a2 = doubles
         lw    $a3,  8($s0)      # $a3 = triples
         lw    $s5, 16($s0)      # $s5 = home runs
         lw    $s4, 12($s0)      # $s4 = outs

         sw    $s4, -4($sp)      # put outs at top of average's stack
         sw    $s5, -8($sp)      # put homeruns 2nd fm top of average's stack
         addi  $a0, $zero, 2     # $a0 = 1 = compute batting average
         jal   average

         # Print the slugging percentage
         mtc1  $v0, $f12         # get result fm $v0 before we print string
         la    $a0, mainSluggingPercentage
         addi  $v0, $zero, 4
         syscall
         addi  $v0, $zero, 2     # print the average
         syscall
         la    $a0, mainNewline
         addi  $v0, $zero, 4
         syscall
         syscall

         addi  $s6, $s6, 1       # i++
         addi  $s0, $s0, 20      # $s0 = addr of next batter's stats
         j     mainLoopBegin

mainDone:
         # Epilogue for main -- restore stack & frame pointers and return
         lw    $ra, 4($sp)       # get return address from stack
         lw    $fp, 0($sp)       # restore frame pointer for caller
         addiu $sp, $sp, 24      # restore frame pointer for caller
         jr    $ra               # return to caller

.data
printHitsOuts:
         .asciiz "Outs:     "
printHitsSingles:
         .asciiz "Singles:  "
printHitsDoubles:
         .asciiz "Doubles:  "
printHitsTriples:
         .asciiz "Triples:  "
printHitsHomeruns:
         .asciiz "Homeruns: "
printHitsNewline:
         .asciiz "\n"

.text
printHits:
         # Function prologue
         addiu $sp, $sp, -28     # allocate stack space
         sw    $fp, 0($sp)       # save frame pointer of caller
         sw    $ra, 4($sp)       # save return address
         sw    $a0, 8($sp)       # save $a0 thru $a3
         sw    $a1, 12($sp)
         sw    $a2, 16($sp)
         sw    $a3, 20($sp)
         addiu $fp, $sp, 24      # setup frame pointer of average

         # print the outs
         la    $a0, printHitsOuts
         addi  $v0, $zero, 4
         syscall
         lw    $a0, 24($sp)      # the outs are at the top of our stack
         addi  $v0, $zero, 1
         syscall
         la    $a0, printHitsNewline
         addi  $v0, $zero, 4
         syscall

         # print the singles
         la    $a0, printHitsSingles
         addi  $v0, $zero, 4
         syscall
         lw    $a0, 8($sp)
         addi  $v0, $zero, 1
         syscall
         la    $a0, printHitsNewline
         addi  $v0, $zero, 4
         syscall

         # print the doubles
         la    $a0, printHitsDoubles
         addi  $v0, $zero, 4
         syscall
         addi  $a0, $a1, 0
         addi  $v0, $zero, 1
         syscall
         la    $a0, printHitsNewline
         addi  $v0, $zero, 4
         syscall

         # print the triples
         la    $a0, printHitsTriples
         addi  $v0, $zero, 4
         syscall
         addi  $a0, $a2, 0
         addi  $v0, $zero, 1
         syscall
         la    $a0, printHitsNewline
         addi  $v0, $zero, 4
         syscall

         # print the homeruns
         la    $a0, printHitsHomeruns
         addi  $v0, $zero, 4
         syscall
         addi  $a0, $a3, 0
         addi  $v0, $zero, 1
         syscall
         la    $a0, printHitsNewline
         addi  $v0, $zero, 4
         syscall

printHitsDone:
         # Epilogue for average -- restore stack & frame pointers and return
         lw    $ra, 4($sp)       # get return address from stack
         lw    $fp, 0($sp)       # restore frame pointer for caller
         addiu $sp, $sp, 28      # restore frame pointer for caller
         jr    $ra               # return to caller

# Your code goes below this line







# $s1 = Homeruns = $f6
# Outs = $f8
# atBats = $f10
# $a1 = Singles = $f12
# $a2 = Doubles = $f14
# $a3 = Triples = $f16
# $f20 = Slugging Percentage (Not Divided)
# $f18 = Hits
# $f2 = Batting Average

average:
         # Function prologue
         addiu $sp, $sp, -56     # allocate stack space
         sw    $fp, 0($sp)       # save frame pointer of caller
         sw    $ra, 4($sp)       # save return address
         sw    $a0, 8($sp)       # 1 or 2 ; 1, batting average ; 2, slugging percentage
         sw    $a1, 12($sp)      # Number of Singles
         sw    $a2, 16($sp)      # Number of Doubles
         sw    $a3, 20($sp)      # Number of Triples
         addiu $fp, $sp, 24      # setup frame pointer of average
         sw    $s0, 28($sp)
         sw    $s1, 32($sp)
         sw    $s2, 36($sp)
         sw    $s3, 40($sp)
         sw    $s4, 44($sp)

         # Grab Outs and Homeruns from Top of Main stack
         lw    $s0, 52($sp)      # Number of Outs
         lw    $s1, 48($sp)      # Number of Homeruns

         # Convert Everything to Floating
         mtc1  $s1, $f6       # $f6 = Homeruns
         mtc1  $s0, $f8       # $f8 = Outs
         mtc1  $a1, $f12      # $f12 = Singles
         mtc1  $a2, $f14      # $f14 = Doubles
         mtc1  $a3, $f16      # $f16 = Triples


         # Calculate Hits ($f18)
         add.s $f18, $f12, $f14  # Add Singles and Doubles
         add.s $f18, $f18, $f16  # Add Triples
         add.s $f18, $f18, $f6   # Add Homeruns

         #Calculate atBats ($f10)
         add.s $f10, $f8, $f18   # Add Outs and Hits

         #Check if Batting or Slugging is to be computed
         add $s4, $zero, $zero
         addi $s4, $s4, 2
         beq $s4, $a0, averageSlugging

averageBatting:
         #Skip when atBats = 0
         mfc1 $s3, $f10
         beqz $s3, averageFinish

         #Calculate Batting Average ($f4)
         div.s $f4, $f18, $f10  # Divide Hits by atBats
         j averageFinish

averageSlugging:
         #Skip when atBats = 0
         mfc1 $s3, $f10
         beqz $s3, averageFinish

         #Calculate Slugging Average ($f0)
         add.s $f20, $f12, $f14       # $f20 = Singles + Doubles
         add.s $f20, $f20, $f14       # $f20 = Singles + Doubles*2
         add.s $f20, $f20, $f16       # $f20 = Singles + Doubles*2 + Triples
         add.s $f20, $f20, $f16       # $f20 = Singles + Doubles*2 + Triples*2
         add.s $f20, $f20, $f16       # $f20 = Singles + Doubles*2 + Triples*3
         add.s $f20, $f20, $f6       # $f20 = Singles + Doubles*2 + Triples*3 + Homeruns
         add.s $f20, $f20, $f6       # $f20 = Singles + Doubles*2 + Triples*3 + Homeruns*2
         add.s $f20, $f20, $f6       # $f20 = Singles + Doubles*2 + Triples*3 + Homeruns*3
         add.s $f20, $f20, $f6       # $f20 = Singles + Doubles*2 + Triples*3 + Homeruns*4

         div.s $f4, $f20, $f10    # Divide Hits by atBats

averageFinish:
         #Call printHits
         add $a0, $a1, $zero     # $a0 = Singles
         add $a1, $a2, $zero     # $a1 = Doubles
         add $a2, $a3, $zero     # $a2 = Triples
         add $a3, $s1, $zero     # $a3 = Homeruns
         sw  $s0, -4($sp)        # Outs at the top of printHits Stack

         jal printHits

         #Prepare for Return
         mfc1 $v0, $f4
         mtc1  $zero, $f4       # $f4 = 0

         # Epilogue for average -- restore stack & frame pointers and return
         lw    $ra, 4($sp)       # get return address from stack
         lw    $fp, 0($sp)       # restore frame pointer for caller
         lw    $a0, 8($sp)       # 1 or 2 ; 1, batting average ; 2, slugging percentage
         lw    $a1, 12($sp)      # Number of Singles
         lw    $a2, 16($sp)      # Number of Doubles
         lw    $a3, 20($sp)      # Number of Triples
         lw    $s0, 28($sp)
         lw    $s1, 32($sp)
         lw    $s2, 36($sp)
         lw    $s3, 40($sp)
         lw    $s4, 44($sp)
         addiu $sp, $sp, 56      # restore frame pointer for caller
         jr    $ra               # return to caller
#用三个击球手进行测试,包括平均击球率和击球率
#第一击球手没有安打,但有出局
#第二个击球手有安打和出局,具有现实价值
#第三击手对一些命中率和第三击有很大的价值
#出局。这意味着命中率和出局率*必须*从整数转换而来
#浮动是为了得到正确的答案。
.数据
mainNumBatters:
.单词3
主要问题1:
.单词0,0,0,15,0#没有atBats的玩家
主要问题2:
.word 101#单打
.word 22双倍
.word 4三元组
.word 423#输出
.word 10#本垒打
主要问题3:
.word 8000000单打
.word 22双倍
.word 500000三倍
.字23000000#出
.word 10#本垒打
主线:
.asciiz“\n”
主打电话号码:
.asciiz“电池编号:”
维护平均值:
.asciiz“击球平均数:”
维修保养百分比:
.asciiz“缓动百分比:”
.文本
主要内容:
#函数序言——即使是main也有一个
subu$sp,$sp,24#分配堆栈空间--此处默认为24
sw$fp,0($sp)#保存调用者的帧指针
sw$ra,4($sp)#保存回信地址
addiu$fp,$sp,20#主屏幕的设置帧指针
#对于(i=0;i     # Convert Everything to Floating
     mtc1  $s1, $f6       # $f6 = Homeruns
     cvt.s.w $f6, $f6     # (convert to floating point)
     mtc1  $s0, $f8       # $f8 = Outs
     cvt.s.w $f8, $f8
     mtc1  $a1, $f12      # $f12 = Singles
     cvt.s.w $f12, $f12
     mtc1  $a2, $f14      # $f14 = Doubles
     cvt.s.w $f14, $f14
     mtc1  $a3, $f16      # $f16 = Triples
     cvt.s.w $f16, $f16