使用除法计算 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%,那么可以只使用整数运算来完成,但使用浮点数可能更简单。