使用除法计算 MIPS 中的百分比分数
Calculate score as a percentage in MIPS using division
我正在制作一个小的数学测验程序,询问玩家基本的数学问题并记录他们的总分。最后我想计算并显示他们的总分百分比。表示回答正确的问题总数的百分比。但是,我绞尽脑汁想弄清楚如何让该百分比正确显示。计算百分比的数学运算全部在 exit 函数中完成,但我将整个程序附加到上下文中。它备受关注。请告诉我如何才能使最终结果正确。
另外,顺便问一下,有没有更好的做除法题的方法?目前我能做到的唯一方法是得到没有余数的商...这显然是一个蹩脚的解决方案。
.data
startMsg: .asciiz "Hello, welcome to MathQuiz, here is your first problem:\nEnter -100 to exit\n"
qf1: .asciiz "What is "
qf2: .asciiz "? "
a1: .asciiz "Correct!\n"
a2: .asciiz "Incorrect!\n"
emf1: .asciiz "You solved "
emf2: .asciiz " math problems and got "
emf3: .asciiz " correct and "
emf4: .asciiz " incorrect, for a score of "
emf5: .asciiz "%.\nThanks for playing!"
operator1: .asciiz " + "
operator2: .asciiz " - "
operator3: .asciiz " * "
operator4: .asciiz " % "
totalCount: .word -1
correctCount: .word 0
incorrectCount: .word 0
scoreCalc: .word 0
correctAnswer: .word 0
wrongAnswer: .word 0
derp: .word 0
.text
.globl main
main:
li $v0, 4 # greet the user
la $a0, startMsg
syscall
calc:
# the primary function that handles most of the calculations.
li $s5, -100 #use register s5 as the exit program value.
# operator reference table
li $t2, 0
li $t3, 1
li $t4, 2
li $t5, 3
li $a1, 21 # set range for random number to 0-20
li $v0, 42 # generate random number, saved in $a0
syscall
move $s1, $a0 # Move random number to register s1
li $a1, 21 # set range for random number to 0-20
li $v0, 42 # generate random number, saved in $a0
syscall
move $s2, $a0 # Move random number to register s2
li $a1, 4 # set range for random number to 0-3
li $v0, 42 # generate random number, saved in $a0
syscall
move $t1, $a0 # Move random number to register s2
# operator table
beq $t1, $t2, addition
beq $t1, $t3, subtraction
beq $t1, $t4, multiplication
beq $t1, $t5, division
addition:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
add $s3, $s1, $s2 # perform the addition of the 2 random numbers.
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
subtraction:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator2 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
sub $s3, $s1, $s2 # perform the subtraction of the 2 random numbers.
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
multiplication:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator3 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
mul $s3, $s1, $s2 # perform the addition of the 2 random numbers.
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
division:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator4 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
div $s1, $s2 # perform the addition of the 2 random numbers.
mflo $s3
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
correct:
# produce the incorrect answer response and adjust counter.
li $v0,4 # output an ascii string.
la $a0, a1 # load the ascii string qf1 for output to screen.
syscall
lw $t1, correctCount # load the value of the correctCount variable into a register.
add $t2, $t1, 1 # add 1 to the value for correctCount in the register.
sw $t2, correctCount # save the iterated value of correctCount back into the memory space of the variable.
j calc # jump back to the calc function to ask another question.
incorrect:
# produce the incorrect answer response and adjust counter.
li $v0,4 # output an ascii string.
la $a0, a2 # load the ascii string qf1 for output to screen.
syscall
lw $t1, incorrectCount # load the value of the incorrectCount variable into a register.
add $t2, $t1, 1 # add 1 to the value for incorrectCount in the register.
sw $t2, incorrectCount # save the iterated value of incorrectCount back into the memory space of the variable.
j calc # jump back to the calc function to ask another question.
exit:
# perform the calculations needed to produce the final output to the user.
lw $t1, totalCount # load the totalCount value into a register
lw $t2, correctCount # load the correctCount value into the register
li $t5, 100 # set a register to 100 for use in the percentage conversion process.
div $t2, $t1 # calculate the players total correct score percentage using division.
mflo $t3 # move the lo register value to $t3 for further calculations.
mul $t6, $t3, $t5 # multiply the score value by 100 to convert to a whole number for output.
# Assemble the output
li $v0, 4 # output an ascii string
la $a0, emf1 # load end message fragment 1 into the registr for output.
syscall
lw $a0, totalCount # load the value of totalCount to register a0 for output.
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf2 # load end message fragment 2 into the registr for output.
syscall
lw $a0, correctCount # load the value of correctCount to register a0 for output.
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf3 # load end message fragment 3 into the registr for output.
syscall
lw $a0, incorrectCount # load the value of incorrectCount to register a0 for output.
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf4 # load end message fragment 4 into the registr for output.
syscall
move $a0, $t6
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf5 # load end message fragment 5 into the registr for output.
syscall
li $v0, 10 #exits the program on syscall
syscall
当你做整数除法时,你总是得到 0。随后乘以 100 无法恢复丢失的分数。最简单的解决办法就是先乘以100再除法
要四舍五入到最接近的整数百分比,请将正确的数字乘以 100,加上问题数量的一半,然后除以问题数量。例如,如果有 12 个问题,其中 8 个正确,则 (8 x 100 + 6) / 12 = 67%.
如果你想要一个百分比的分数,比如 66.7%,那么可以只使用整数运算来完成,但使用浮点数可能更简单。
我正在制作一个小的数学测验程序,询问玩家基本的数学问题并记录他们的总分。最后我想计算并显示他们的总分百分比。表示回答正确的问题总数的百分比。但是,我绞尽脑汁想弄清楚如何让该百分比正确显示。计算百分比的数学运算全部在 exit 函数中完成,但我将整个程序附加到上下文中。它备受关注。请告诉我如何才能使最终结果正确。
另外,顺便问一下,有没有更好的做除法题的方法?目前我能做到的唯一方法是得到没有余数的商...这显然是一个蹩脚的解决方案。
.data
startMsg: .asciiz "Hello, welcome to MathQuiz, here is your first problem:\nEnter -100 to exit\n"
qf1: .asciiz "What is "
qf2: .asciiz "? "
a1: .asciiz "Correct!\n"
a2: .asciiz "Incorrect!\n"
emf1: .asciiz "You solved "
emf2: .asciiz " math problems and got "
emf3: .asciiz " correct and "
emf4: .asciiz " incorrect, for a score of "
emf5: .asciiz "%.\nThanks for playing!"
operator1: .asciiz " + "
operator2: .asciiz " - "
operator3: .asciiz " * "
operator4: .asciiz " % "
totalCount: .word -1
correctCount: .word 0
incorrectCount: .word 0
scoreCalc: .word 0
correctAnswer: .word 0
wrongAnswer: .word 0
derp: .word 0
.text
.globl main
main:
li $v0, 4 # greet the user
la $a0, startMsg
syscall
calc:
# the primary function that handles most of the calculations.
li $s5, -100 #use register s5 as the exit program value.
# operator reference table
li $t2, 0
li $t3, 1
li $t4, 2
li $t5, 3
li $a1, 21 # set range for random number to 0-20
li $v0, 42 # generate random number, saved in $a0
syscall
move $s1, $a0 # Move random number to register s1
li $a1, 21 # set range for random number to 0-20
li $v0, 42 # generate random number, saved in $a0
syscall
move $s2, $a0 # Move random number to register s2
li $a1, 4 # set range for random number to 0-3
li $v0, 42 # generate random number, saved in $a0
syscall
move $t1, $a0 # Move random number to register s2
# operator table
beq $t1, $t2, addition
beq $t1, $t3, subtraction
beq $t1, $t4, multiplication
beq $t1, $t5, division
addition:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
add $s3, $s1, $s2 # perform the addition of the 2 random numbers.
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
subtraction:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator2 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
sub $s3, $s1, $s2 # perform the subtraction of the 2 random numbers.
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
multiplication:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator3 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
mul $s3, $s1, $s2 # perform the addition of the 2 random numbers.
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
division:
li $v0,4 # output an ascii string
la $a0, qf1 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s1
syscall
li $v0,4 # output an ascii string
la $a0, operator4 # load the ascii string qf1 for output to screen
syscall
li $v0,1 # output an int
move $a0, $s2
syscall
li $v0,4 # output an ascii string.
la $a0, qf2 # load the ascii string qf2 for output to screen.
syscall
li $v0, 5 # read an integer from the command line, result saved in $v0.
syscall
move $s4, $v0 # move the user input to a register for comparison.
div $s1, $s2 # perform the addition of the 2 random numbers.
mflo $s3
lw $t1, totalCount # load the current value of totalCount into a register.
add $t2, $t1, 1 # add 1 to the value in the register for totalCount.
sw $t2, totalCount # save the iterated value of totalCount back to the memory space of the variable.
beq $s4, $s5, exit # if the user input matches -1, jump to "exit" function.
beq $s4, $s3, correct # if user input matches the correct answer, jump to the "correct" function.
j incorrect # if the answer is wrong AND not "-1", jump to the "incorrect" function.
correct:
# produce the incorrect answer response and adjust counter.
li $v0,4 # output an ascii string.
la $a0, a1 # load the ascii string qf1 for output to screen.
syscall
lw $t1, correctCount # load the value of the correctCount variable into a register.
add $t2, $t1, 1 # add 1 to the value for correctCount in the register.
sw $t2, correctCount # save the iterated value of correctCount back into the memory space of the variable.
j calc # jump back to the calc function to ask another question.
incorrect:
# produce the incorrect answer response and adjust counter.
li $v0,4 # output an ascii string.
la $a0, a2 # load the ascii string qf1 for output to screen.
syscall
lw $t1, incorrectCount # load the value of the incorrectCount variable into a register.
add $t2, $t1, 1 # add 1 to the value for incorrectCount in the register.
sw $t2, incorrectCount # save the iterated value of incorrectCount back into the memory space of the variable.
j calc # jump back to the calc function to ask another question.
exit:
# perform the calculations needed to produce the final output to the user.
lw $t1, totalCount # load the totalCount value into a register
lw $t2, correctCount # load the correctCount value into the register
li $t5, 100 # set a register to 100 for use in the percentage conversion process.
div $t2, $t1 # calculate the players total correct score percentage using division.
mflo $t3 # move the lo register value to $t3 for further calculations.
mul $t6, $t3, $t5 # multiply the score value by 100 to convert to a whole number for output.
# Assemble the output
li $v0, 4 # output an ascii string
la $a0, emf1 # load end message fragment 1 into the registr for output.
syscall
lw $a0, totalCount # load the value of totalCount to register a0 for output.
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf2 # load end message fragment 2 into the registr for output.
syscall
lw $a0, correctCount # load the value of correctCount to register a0 for output.
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf3 # load end message fragment 3 into the registr for output.
syscall
lw $a0, incorrectCount # load the value of incorrectCount to register a0 for output.
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf4 # load end message fragment 4 into the registr for output.
syscall
move $a0, $t6
li, $v0, 1 # output an int
syscall
li $v0, 4 # output an ascii string
la $a0, emf5 # load end message fragment 5 into the registr for output.
syscall
li $v0, 10 #exits the program on syscall
syscall
当你做整数除法时,你总是得到 0。随后乘以 100 无法恢复丢失的分数。最简单的解决办法就是先乘以100再除法
要四舍五入到最接近的整数百分比,请将正确的数字乘以 100,加上问题数量的一半,然后除以问题数量。例如,如果有 12 个问题,其中 8 个正确,则 (8 x 100 + 6) / 12 = 67%.
如果你想要一个百分比的分数,比如 66.7%,那么可以只使用整数运算来完成,但使用浮点数可能更简单。