|
Professional Programmer
Join Date: Oct 2006
Posts: 311
Rep Power: 3 
|
Re: Masm32 adding two floats
Actually I was incorrect in saying that I got it right. He might not notice and still give me extra credit though, depending on how harsh his input testing is. But it shouldn't be that harsh since he said in class that if you gave a 'good faith effort' you would get 100. Apparently a lot of people couldn't even read in the values from the user. For some reason, my code worked as long as the user entered 42 values or less (although the project description said to let them enter up to 100). But if the user entered > 42 values, the code didn't give the right answer anymore. My friend looked at it and tried to fix it (his project worked completely) and couldn't figure out what was different that it didn't work. When he got done changing some shit around, it only accepted up to 40 values while working correctly. This was all tried on my machine - I'm not sure if that matters. I'm going to post the code, I'm hoping someone can try to run it and see if it works for you.... also, maybe someone can spot an error that causes this problem. Its looping through the "correct number of times" in all cases... it just generates the wrong results when you enter more than 40 values.
This post is the full code. Below this post, I'm posting some 'areas of interest' that i think could possibly be causing it. Of course, I don't know that for a fact otherwise I'd have fixed it, so it could be anywhere, really. But I tried some print statements and such to make sure values are what I expected, and they are...so i don't know whats going on.
;
;;;; CONSOLE ASSEM & LINK to compile.
include \masm32\include\masm32rt.inc
.code
start:
call main
inkey
exit
main proc
LOCAL myArray[100]:QWORD
LOCAL nrValues:DWORD
LOCAL getValues:DWORD
cls
finit
;; call the functions to get the num of values from user
;; put them in an array, average them, and print them out
call getNrValues
mov [nrValues], eax
mov edi, [nrValues]
call storeUserInput
mov ecx, [nrValues]
call calculateAvg
call displayAvg
ret
main endp
;/***********************************************************
; Function name: getNrValues
; ***********************************************************
getNrValues proc
LOCAL myValue:DWORD
LOCAL above:DWORD
LOCAL below:DWORD
;; a loop to force the user to input a number between 10 and 100
outOfRange:
print chr$(10,13)
mov myValue, sval(input("Enter a number between 10 and 100: ") )
print "You entered "
print str$(myValue)
mov [above],100
mov [below],10
mov edi,[myValue]
cmp edi,[below]
jl outOfRange ;; if the user input a number below 10, ask to reinput
mov edi,[myValue]
cmp edi,[above]
jg outOfRange ;; if the user input a nr above 100, ask to reinput
print " which is valid input."
print chr$(10,13)
mov eax,[myValue]
ret
getNrValues endp
;/***********************************************************
; * Function name: storeUserInput
; ***********************************************************/
storeUserInput proc
LOCAL myFP:QWORD
LOCAL myArray[100]:QWORD
LOCAL arrayAddr:DWORD
LOCAL myString:DWORD
LOCAL answer1[20]:BYTE
mov ecx, edi
lea edi, myArray ; edi holds the address of myArray
forloop:
push ecx
mov eax,input("Enter a floating pt. number then hit enter: ") ; gets the String
mov ebx, eax
push edi
invoke StrToFloat,ebx,ADDR myFP ; converts the String to a float and puts it in myFP
pop edi
lea ebx, myFP ;; ebx holds the addr of the FP
mov eax, [ebx] ;; eax holds the value of the FP
mov [edi], eax ;; the array holds the value of the FP
add ebx, 4 ;;
mov eax, [ebx] ;; eax holds the second part of the FP
mov [edi+4], eax ;; the value at addr + 4 is now the FP
add edi, 8
pop ecx
loop forloop
lea edi, myArray
mov eax, ecx
ret
storeUserInput endp
;/***********************************************************
; * Function name: calculateAvg *
; ***********************************************************/
calculateAvg proc
LOCAL arrayAddr:DWORD
LOCAL myFP1:QWORD
LOCAL counter:DWORD
LOCAL answer1[20]:BYTE
LOCAL total:DWORD
LOCAL nrValues:DWORD
mov [nrValues], ecx
push ecx
mov [total], 0
print chr$(13,10)
fldz
mov esi, edi
pop ecx
aLoop:
push ecx
;; get the value the user entered
lea ebx, myFP1
mov eax, [esi]
mov [ebx], eax
add ebx, 4
mov eax, [esi+4]
mov [ebx], eax
fld myFP1
fadd
add esi, 8
;; convert the value to a string then print it out
push esi
invoke FloatToStr,myFP1,ADDR answer1
print "The value you entered was "
invoke StdOut,ADDR answer1; print as float
print chr$(10,13)
pop esi
pop ecx
loop aLoop
fidiv [nrValues] ;; get the average of the floats the user entered
ret
calculateAvg endp
;/***********************************************************
; * Function name: displayAvg
; ***********************************************************/
displayAvg proc
LOCAL myFP1:QWORD
LOCAL answer1[20]:BYTE
;; print out the average of the floats the user entered
fstp [myFP1]
print chr$(13,10,13,10)
print "The average of the values you entered is "
invoke FloatToStr,myFP1,ADDR answer1
invoke StdOut,ADDR answer1
print chr$(13,10)
ret
displayAvg endp
end start
Last edited by Fall Back Son; Mar 31st, 2008 at 7:48 PM.
|