Reputation: 51
I am making a little math quiz program that asks the player basic math questions and keeps a tally of their total score. At the end I want to calculate and display their total score as a percent. Meaning what percent of total questions asked, were answered correctly. However, I have wracked my brain trying to figure out how to get that percentage to display correctly. The math to calculate the percent is all being done in the exit function but I am attaching the entire program for context. Its heavily noted. Please advise on what I could do to make that final result correct.
Also, as an aside, is there a better way to do the division question? Currently the only way i can do it to have the answer be the quotient with no remainder... this is obviously a crappy solution.
.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
Upvotes: 1
Views: 439
Reputation: 12432
When you do the integer division, you always get 0. Subsequently multiplying by 100 cannot recover the lost fraction. The easiest solution is to multiply by 100 first and then divide.
To round to the nearest whole percent, multiply the number correct by 100, add half of the number of questions, then divide by the number of questions. For example, if there are 12 questions and 8 are correct, (8 x 100 + 6) / 12 = 67%.
If you want a fraction of a percent, such as 66.7%, then it can be done using only integer operations, but it is probably simpler to use floating point.
Upvotes: 2