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