The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: etow on January 30, 2008, 03:13:23 PM

Title: Quadratic Square Root Code Problem
Post by: etow on January 30, 2008, 03:13:23 PM
Hi I am having trouble with my code below:
--------------------------------------------------------------------------------------------------------------------------

.686 ; create 32 bit code

.Model flat, StdCall  ;32 bit memory model
Option CaseMap :none  ; case sensitive

Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm       ; MASM support macros

  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
Include \masm32\include\masm32rt.inc

  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
IncludeLib \masm32\lib\msvcrt.lib

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey        ; pause the screen while waiting for user to press any key
             ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Main Proc
  Local WantContinue:DWord
  Local NumberA:DWord
  Local NumberB:DWord
  Local NumberC:DWord

    Mov WantContinue, 0

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10)
       Mov NumberA, sval(input("Enter an integer value for Number A : "))
       Mov NumberB, sval(input("Enter an integer value for Number B : "))
       Mov NumberC, sval(input("Enter an integer value for Number C : "))
       print chr$(13, 10)
       Call calculateQuadraticRoots NumberA, NumberB, NumberC
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
    .EndW
  Ret
Main EndP

calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
  Local squareRootNumber:DWord
  Local partSquareRootNumber:DWord
  Local BSquared:DWord
  Local NegB:DWord
  Local resultOfSquareRoot:DWord


  Neg B_Number

  Mov Eax, B_Number
  Add Eax, Eax
  Mov BSquared, Eax     ;  b^2

  Mov Eax, A_Number
  IMul C_Number
  Mov Ebx, Eax
  Mov Eax, -4          ;  -4 * a * c

  Mov Eax, partSquareRootNumber
  Mov Ebx, squareRootNumber

  Add Ebx, Eax
  Mov squareRootNumber, Ebx

  Call Intsqrt squareRootNumber
  Mov resultOfSquareRoot, Eax

  Ret
calculateQuadraticRoots EndP

End start

----------------------------------------------------------------------------------------------

I am receiving the following error messages:

============== proj4 - Debug ==============

Assembling: Module1
Module1.asm(3) : warning A4011: multiple .MODEL directives found : .MODEL ignored
------------------------------------------
WARNING Duplicate include file windows.inc
------------------------------------------
\masm32\include\masm32rt.inc(33) : warning A4011: multiple .MODEL directives found : .MODEL ignored
------------------------------------------
WARNING Duplicate include file windows.inc
------------------------------------------
-----------------------------------------
WARNING Duplicate include file user32.inc
-----------------------------------------
-----------------------------------------
WARNING Duplicate include file kernel32.inc
-----------------------------------------
Module1.asm(44) : error A2008: syntax error : ,
Module1.asm(77) : error A2206: missing operator in expression

Errors ocurred.

Title: Re: Quadratic Square Root Code Problem
Post by: jdoe on January 30, 2008, 04:23:07 PM
etow,

You have a strange way to learn. Looks like try, try, try until it work, instead of learning how to do.

You already got your answer for duplicates and .MODEL
http://www.masm32.com/board/index.php?topic=8576.msg62394#msg62394
http://www.masm32.com/board/index.php?topic=8576.msg62395#msg62395

When you see "Module1.asm(44) : error A2008: syntax error : ," the "Module1.asm(44)" means that the error is at line 44
Look for "Using invoke" in the help file "masm32" in the help folder of MASM32 Project

Title: Re: Quadratic Square Root Code Problem
Post by: MichaelW on January 30, 2008, 05:12:15 PM
etow,

Here is your source with the minimal corrections necessary to make it assemble and link without error.

;;INCLUDED IN masm32rt.inc: .686 ;create 32 bit code
;;INCLUDED IN masm32rt.inc: .Model flat, StdCall ;32 bit memory model
;;INCLUDED IN masm32rt.inc: Option  CaseMap :none ;case sensitive

;;INCLUDED IN masm32rt.inc: Include \masm32\include\windows.inc
;;INCLUDED IN masm32rt.inc: Include \masm32\macros\macros.asm

Include \masm32\include\masm32rt.inc

;;INCLUDED IN masm32rt.inc: IncludeLib \masm32\lib\msvcrt.lib

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey ; pause the screen while waiting for user to press any key
    ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; ----------------------------------------------------------------
; This is the prototype for the calculateQuadraticRoots procedure:
; ----------------------------------------------------------------

calculateQuadraticRoots PROTO :DWord,:DWord,:DWord

Main Proc
  Local WantContinue:DWord
  Local NumberA:DWord
  Local NumberB:DWord
  Local NumberC:DWord

    Mov WantContinue, 0
    .While ((WantContinue >= 0) && (WantContinue < -1))
      print chr$(13, 10)
      Mov NumberA, sval(input("Enter an integer value for Number A : "))
      Mov NumberB, sval(input("Enter an integer value for Number B : "))
      Mov NumberC, sval(input("Enter an integer value for Number C : "))
      print chr$(13, 10)

      ; --------------------------------------------------
      ; To pass arguments in this way you must use invoke.
      ; And to use invoke for a procedure that is defined
      ; after it is invoked, you must provide a prototype
      ; so MASM will know how to call it.
      ; --------------------------------------------------

      ;Call calculateQuadraticRoots NumberA, NumberB, NumberC
      invoke calculateQuadraticRoots, NumberA, NumberB, NumberC

      print chr$(13, 10)
      Mov WantContinue, sval(input("Enter -1 to quit program : "))
      print chr$(13, 10)
    .EndW
    Ret
Main EndP

; -----------------------------------------------------------------
; This is the definition for the calculateQuadraticRoots procedure:
; -----------------------------------------------------------------

calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
    Local squareRootNumber:DWord
    Local partSquareRootNumber:DWord
    Local BSquared:DWord
    Local NegB:DWord
    Local resultOfSquareRoot:DWord

    Neg B_Number

    Mov Eax, B_Number
    Add Eax, Eax
    Mov BSquared, Eax     ;  b^2

    Mov Eax, A_Number
    IMul C_Number
    Mov Ebx, Eax
    Mov Eax, -4          ;  -4 * a * c

    Mov Eax, partSquareRootNumber
    Mov Ebx, squareRootNumber

    Add Ebx, Eax
    Mov squareRootNumber, Ebx

    ; ---------------------------------------------------
    ; To pass arguments in this way you must use invoke.
    ; IntSqrt is part of the MASM32 library, so the
    ; prototype is taken care of, but you must use the
    ; correct case for all procedure names, as well as
    ; all of your label and variable names.
    ; ---------------------------------------------------

    ;Call Intsqrt squareRootNumber
    invoke IntSqrt, squareRootNumber

    Mov resultOfSquareRoot, Eax

    Ret
calculateQuadraticRoots EndP

End start
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on January 30, 2008, 05:47:29 PM
Quote from: etow on January 30, 2008, 03:13:23 PM
  Mov Eax, B_Number
  Add Eax, Eax                           
  Mov BSquared, Eax       ;  b^2   
 

etow,
           i think you have an error here:
                                                      ;  b^2    <=  This is   «b + b»  or  «b * b» ?????????????

           Add   Eax, Eax   <= This is eax PLUS eax    NOT   eax * eax   as  you  want
;................................................
You want something like this:


           Mov     Eax, B_Number
           mov     edx, eax
           mul     edx                           
           Mov     BSquared, Eax       ; BSquared = EAX * EAX 
                      
RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on January 30, 2008, 08:58:43 PM
Here is my updated code below:
-------------------------------------------------------------------------------------

.686 ; create 32 bit code

.Model flat, StdCall  ;32 bit memory model
Option CaseMap :none  ; case sensitive

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm       ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey        ; pause the screen while waiting for user to press any key
             ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Main Proc
  Local WantContinue:DWord
  Local NumberA:DWord
  Local NumberB:DWord
  Local NumberC:DWord

    Mov WantContinue, 0

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10)
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       Mov NumberA, sval(input("Enter an integer value for Number A : "))
       Mov NumberB, sval(input("Enter an integer value for Number B : "))
       Mov NumberC, sval(input("Enter an integer value for Number C : "))
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
    .EndW
  Ret
Main EndP

calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
  Local squareRootNumber:DWord
  Local partSquareRootNumber:DWord
  Local BSquared:DWord
  Local originalB_Number:DWord
  Local negativeB:DWord
  Local resultOfSquareRoot:DWord
  Local numerator1:DWord
  Local numerator2:DWord
  Local denominator:DWord
  Local realRoot1:FLOAT
  Local realRoot2:FLOAT

; Quadratic Equation:  (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

  Mov Ebx, B_Number
  Mov originalB_Number, Ebx

  Mov Eax, B_Number
  Mov Edx, Eax
  Mul Edx
  Mov BSquared, Eax     ;  b^2

  Mov Eax, A_Number
  IMul C_Number
  Mov Ebx, Eax
  Mov Eax, -4
  IMul Ebx              ; -4 * a * c

  Mov partSquareRootNumber, Eax

  Mov Eax, BSquared
  Mov Ebx, partSquareRootNumber

  Add Eax, Ebx
  Mov squareRootNumber, Eax  ;  b^2 - 4 * a * c

  .If (squareRootNumber >= 0)
     Invoke IntSqrt, squareRootNumber
     Mov resultOfSquareRoot, Eax

     Neg B_Number
     Mov Eax, B_Number
     Mov negativeB, Eax  ; -b

     Mov Eax, 2
     IMul A_Number
     Mov denominator, Eax   ;  2 * a

     Mov Eax, negativeB
     Mov Ebx, resultOfSquareRoot
     Add Eax, Ebx
     Mov numerator1, Eax         ; (- b + sqrt(b^2 - 4 * a * c))

     Neg resultOfSquareRoot
     Mov Eax, resultOfSquareRoot
     Mov Ebx, negativeB
     Add Eax, Ebx
     Mov numerator2, Eax         ; (- b  - sqrt(b^2 - 4 * a * c))

     Mov Eax, numerator1
     Div denominator
     Mov realRoot1, Eax          ; (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)

     Mov Eax, numerator2
     Div denominator
     Mov realRoot2, Eax          ; (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)

     print chr$(13, 10)
     print chr$(" Solutions for quadratic equation : ")

     .If (A_Number == 1)
      print chr$("X^2 ")
     .ElseIf
        print str$(A_Number)
        print chr$("X^2 ")
     .EndIf

     .If (originalB_Number == 1)
      print chr$("+ X ")
     .ElseIf (originalB_Number < SDWord Ptr - 1)
      print str$(originalB_Number)
      print chr$("X ")
     .ElseIf (originalB_Number == -1)
      print chr$("- X ")
     .ElseIf (originalB_Number > 1)
      print chr$("+ ")
      print str$(originalB_Number)
        print chr$("X ")
     .EndIf

     .If (C_Number < SDWord Ptr - 1)
        print str$(C_Number)
     .ElseIf (C_Number == -1)
      print chr$("- ")
        print chr$("1")
     .ElseIf (C_Number > 0)
      print chr$("+ ")
      print str$(C_Number)
     .EndIf

     print chr$(13, 10)

     print chr$(" X1 = ")
     print str$(realRoot1)
     print chr$(13, 10)
     print chr$(" X2 = ")
     print str$(realRoot2)
     print chr$(13, 10)

  .ElseIf (squareRootNumber < SDWord Ptr 0)
  print chr$(13, 10)
     print chr$("There are no real solutions to this quadratic equation!")
     print chr$(13, 10)
  .EndIf

  Ret
calculateQuadraticRoots EndP

End start


------------------------------------------------------------------------------------------
I can not get the second X solution to the quadratic equation to calculate correctly

If I enter 1 for Number A,  enter 0 for Number B,  and enter -4 for Number C,

X1 = 2
X2 = 2147483646

Why is X2 this number above instead of -2?

Please help me.

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on January 30, 2008, 10:10:30 PM
etow,
        1. try to simplify. Dont use a lot of variables that you dont need.
           You can use registers to save some intermediate results (ex: ebx, esi, edi )
           Dont modify the input values like   ***  Neg    B_Number  ***. Use
           *** negativeB variable ***  if you want .
           
        2. I dont know where is the error, your code is not easy to follow. Here my help



  ; Quadratic Equation:  (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
 
  ;Mov   Ebx, B_Number                  ; dont need
  ;Mov   originalB_Number, Ebx          ; dont need
  ;
  ; b ^ 2
  ; -----
  Mov      eax, B_Number           
  Mov      edx, eax
  IMul      edx
  ;Mov      BSquared, eax               ; dont need   
  mov      ebx, eax                 ;  EBX = b ^ 2
  ;
  ; 4 * a * c
  ; ---------
  mov       ecx, 4
  Mov       eax, A_Number
  IMul      C_Number
  IMul      ecx                     ; EAX = 4 * a * c
  ;
  ; b ^ 2 - 4 * a * c
  ; -----------------
  sub       ebx, eax                ; EBX = b ^ 2 - 4 * a * c
  Mov       squareRootNumber, ebx   
  ;
  ; Test
  ;
  .If (squareRootNumber >= 0)
 
     Invoke   IntSqrt, squareRootNumber
     Mov      resultOfSquareRoot, Eax
            .............
           
       

RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on January 30, 2008, 11:59:26 PM
Hi

My updated code below:

-------------------------------------------------------------------------

.686 ; create 32 bit code

.Model flat, StdCall  ;32 bit memory model
Option CaseMap :none  ; case sensitive

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm       ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey        ; pause the screen while waiting for user to press any key
             ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proto:DWord, :DWord, :DWord

Main Proc
  Local WantContinue:DWord
  Local NumberA:DWord
  Local NumberB:DWord
  Local NumberC:DWord

    Mov WantContinue, 0

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10)
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       Mov NumberA, sval(input("Enter an integer value for Number A : "))
       Mov NumberB, sval(input("Enter an integer value for Number B : "))
       Mov NumberC, sval(input("Enter an integer value for Number C : "))
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
    .EndW
  Ret
Main EndP

calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
  Local squareRootNumber:DWord
  Local negativeB:DWord
  Local resultOfSquareRoot:DWord
  Local numerator1:DWord
  Local numerator2:DWord
  Local denominator:DWord
  Local realRoot1:Real4
  Local realRoot2:Real4

; Quadratic Equation:  (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

.If (A_Number != 0)

    Mov Eax, B_Number
    Mov Edx, Eax
    Mul Edx
    Mov Ebx, Eax          ; Ebx = b^2

    Mov Ecx, -4
    Mov Eax, A_Number
    Mul C_Number
    Mul Ecx               ; Eax = -4 * a * c

    Add Ebx, Eax
    Mov squareRootNumber, Ebx   ; ebx =  b^2 - 4 * a * c

   .If (squareRootNumber > SDWord Ptr - 1)
      Invoke IntSqrt, squareRootNumber
      Mov resultOfSquareRoot, Eax

      Mov Eax, B_Number
      Neg Eax
      Mov negativeB, Eax  ; -b

      Mov Eax, 2
      Mul A_Number
      Mov denominator, Eax   ;  eax = 2 * a

      Mov Eax, negativeB
      Mov Ebx, resultOfSquareRoot
      Add Eax, Ebx
      Mov numerator1, Eax       ;  eax = (- b + sqrt(b^2 - 4 * a * c))

      Mov Ebx, resultOfSquareRoot
      Neg Ebx
      Mov Eax, negativeB
      Add Eax, Ebx
      Mov numerator2, Eax       ; eax = (- b  - sqrt(b^2 - 4 * a * c))

      Mov Eax, numerator1
      Div denominator
      Mov realRoot1, Eax       ; eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)

      Mov Eax, numerator2
      Div denominator
      Mov realRoot2, Eax       ; eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      .If (A_Number == -1)
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1)
        print chr$("X^2 ")
      .ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
        print str$(A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1)
      print str$(B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1)
      print chr$("- X ")
      .ElseIf (B_Number == 1)
      print chr$("+ X ")
      .ElseIf (B_Number > 1)
      print chr$("+ ")
      print str$(B_Number)
        print chr$("X ")
      .EndIf

      .If (C_Number < SDWord Ptr - 1)
        print str$(C_Number)
      .ElseIf (C_Number == -1)
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0)
      print chr$("+ ")
      print str$(C_Number)
      .EndIf

      print chr$(13, 10)

      print chr$(" X1 = ")
      print str$(realRoot1)
      print chr$(13, 10)
      print chr$(" X2 = ")
      print str$(realRoot2)
      print chr$(13, 10)

   .ElseIf (squareRootNumber <= SDWord Ptr - 1)
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      .If (A_Number == -1)
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1)
      print chr$("X^2 ")
      .ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
        print str$(A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1)
      print str$(B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1)
      print chr$("- X ")
      .ElseIf (B_Number == 1)
      print chr$("+ X ")
      .ElseIf (B_Number > 1)
      print chr$("+ ")
      print str$(B_Number)
        print chr$("X ")
      .EndIf

      .If (C_Number < SDWord Ptr - 1)
        print str$(C_Number)
      .ElseIf (C_Number == -1)
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0)
      print chr$("+ ")
      print str$(C_Number)
      .EndIf

      print chr$(" !", 13, 10)
   .EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10)
.EndIf
  Ret
calculateQuadraticRoots EndP

End start


---------------------------------------------------------------------------------------------

I am not sure if realRoot1 and realRoot2 are correct in calculation.
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on January 31, 2008, 10:26:44 AM
Quote from: etow on January 30, 2008, 11:59:26 PM

      Mov Eax, numerator1
      Div denominator
      Mov realRoot1, Eax       ; eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)

      Mov Eax, numerator2
      Div denominator
      Mov realRoot2, Eax       ; eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)

I am not sure if realRoot1 and realRoot2 are correct in calculation.
etow,
          ***  Div   denominator    ***  divides  EDX:EAX  by denominator. Whats the value
          of EDX ?
          Put    xor   edx, edx   or    mov edx, 0 before div.

          After   ***    Mov numerator1, Eax   ***      ;  eax = (- b + sqrt(b^2 - 4 * a * c))

          you dont need to repeat  ***  Mov Ebx, resultOfSquareRoot  ***
          because   ebx =resultOfSquareRoot.

RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on January 31, 2008, 02:29:50 PM
hi

how do you do real or floating point division instead of integer division?

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on January 31, 2008, 03:13:33 PM
Quote from: etow on January 31, 2008, 02:29:50 PM
hi
how do you do real or floating point division instead of integer division?

Thanks

              As far as i know, using FPU.

RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on January 31, 2008, 03:48:38 PM
Hi RuiLoureiro,

Can you give me an example how to use FPU?

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: etow on January 31, 2008, 04:46:26 PM
I found out the problem.

the code below:


      Mov Eax, numerator1
      IDiv denominator
      Mov realRoot1, Eax       ; eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)

      Mov Eax, numerator2
      IDiv denominator
      Mov realRoot2, Eax       ; eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)


-------------------------------------------------------------------------------------------------------
if the result in Eax is positive then the result is okay
but if the result in Eax is negative then the result is not good or bad result.

How do I fix this?

Please help

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on January 31, 2008, 06:43:52 PM
Quote from: etow on January 31, 2008, 04:46:26 PM
I found out the problem.
-------------------------------------------------------------------------------------------------------
if the result in Eax is positive then the result is okay
but if the result in Eax is negative then the result is not good or bad result.

Hi etow,
         1. Its not correct. When we want to divide a dword value like numerator1 by a dword value like
           denominator we need to put edx to 0 or the signal of EAX into EDX.
           IDiv denominator    divide    EDX:EAX (64 bits) by denominator. Its clear.

         2. About FPU, see fpulib in MASM32 and tuturial\fputute written by Raymond Filiatreault.
             He should have many examples to help you. The work i am doing now doesnt use FPU, so i
              have not an example to give you. I used it some years ago i dont know where are my routines.
              Sorry.
RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 12:29:03 AM
hi

***  Div   denominator    ***  divides  EDX:EAX  by denominator. Whats the value
          of EDX ?
          Put    xor   edx, edx   or    mov edx, 0 before div.

          After   ***    Mov numerator1, Eax   ***      ;  eax = (- b + sqrt(b^2 - 4 * a * c))


Edx register is 0 after putting mov edx, 0 before div.   I tried the above but it does not work.
If the eax is negative for both realRoot1 and realRoot2 values, then answers are 2147483647.
If the eax is negative for either realRoot1 or realRoot2 values then the answer is 2147483647.
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 12:37:21 AM
Here is my updated code below:


.686 ; create 32 bit code

.Model flat, StdCall  ;32 bit memory model
Option CaseMap :none  ; case sensitive

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm       ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey        ; pause the screen while waiting for user to press any key
             ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proto:DWord, :DWord, :DWord

Main Proc
  Local WantContinue:DWord
  Local NumberA:DWord
  Local NumberB:DWord
  Local NumberC:DWord

    Mov WantContinue, 0

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10)
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       Mov NumberA, sval(input("Enter an integer value for Number A : "))
       Mov NumberB, sval(input("Enter an integer value for Number B : "))
       Mov NumberC, sval(input("Enter an integer value for Number C : "))
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
    .EndW
  Ret
Main EndP

calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
  Local squareRootNumber:DWord
  Local negativeB:DWord
  Local resultOfSquareRoot:DWord
  Local numerator1:DWord
  Local numerator2:DWord
  Local denominator:DWord
  Local realRoot1:DWord
  Local realRoot2:DWord

; Quadratic Equation:  (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

.If (A_Number != 0)

    Mov Eax, B_Number
    Mov Edx, Eax
    IMul Edx
    Mov Ebx, Eax          ; Ebx = b^2

    Mov Ecx, -4
    Mov Eax, A_Number
    IMul C_Number
    IMul Ecx               ; Eax = -4 * a * c

    Add Ebx, Eax
    Mov squareRootNumber, Ebx   ; Ebx =  b^2 - 4 * a * c

   .If (squareRootNumber > SDWord Ptr - 1)
      Invoke IntSqrt, squareRootNumber
      Mov resultOfSquareRoot, Eax

      Mov Eax, B_Number
      Neg Eax
      Mov negativeB, Eax  ; Eax = -b

      Mov Eax, 2
      IMul A_Number
      Mov denominator, Eax   ;  Eax = 2 * a

      Mov Eax, negativeB
      Mov Ebx, resultOfSquareRoot
      Add Eax, Ebx
      Mov numerator1, Eax       ;  Eax = (- b + sqrt(b^2 - 4 * a * c))

      Neg Ebx
      Mov Eax, negativeB
      Add Eax, Ebx
      Mov numerator2, Eax       ; Eax = (- b  - sqrt(b^2 - 4 * a * c))

      Mov Eax, numerator1
      IDiv denominator
      Mov realRoot1, Eax       ; Eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)

      Mov Eax, numerator2
      IDiv denominator
      Mov realRoot2, Eax       ; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      .If (A_Number == -1)
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1)
        print chr$("X^2 ")
      .ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
        print str$(A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1)
      print str$(B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1)
      print chr$("- X ")
      .ElseIf (B_Number == 1)
      print chr$("+ X ")
      .ElseIf (B_Number > 1)
      print chr$("+ ")
      print str$(B_Number)
        print chr$("X ")
     .EndIf

      .If (C_Number < SDWord Ptr - 1)
        print str$(C_Number)
      .ElseIf (C_Number == -1)
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0)
      print chr$("+ ")
    print str$(C_Number)
      .EndIf

      print chr$(13, 10, 13, 10)

      print chr$(" X1 = ")
      print str$(realRoot1)
      print chr$(13, 10)
      print chr$(" X2 = ")
      print str$(realRoot2)
      print chr$(13, 10)

   .ElseIf (squareRootNumber <= SDWord Ptr - 1)
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      .If (A_Number == -1)
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1)
      print chr$("X^2 ")
      .ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
        print str$(A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1)
      print str$(B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1)
      print chr$("- X ")
      .ElseIf (B_Number == 1)
      print chr$("+ X ")
      .ElseIf (B_Number > 1)
      print chr$("+ ")
      print str$(B_Number)
        print chr$("X ")
      .EndIf

      .If (C_Number < SDWord Ptr - 1)
        print str$(C_Number)
      .ElseIf (C_Number == -1)
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0)
      print chr$("+ ")
      print str$(C_Number)
      .EndIf

      print chr$(" !", 13, 10)
   .EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10)
.EndIf
  Ret
calculateQuadraticRoots EndP

End start


----------------------------------------------------------------------------------

I am not sure why Eax register outputs 2147483647 for realRoot1 or realRoot2 or for both?

Can anyone help me?

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: Jimg on February 01, 2008, 12:51:35 AM
hint:  2147483647 decimal = 7FFFFFFF hex = -1 with the topmost bit removed. 
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 01:06:27 AM
for the quadratic equation  x^2 + 7x + 12

X = -3
1
X = -4
2

How can I get these answers for negative numbers above since the highest is  2147483647 positive decimal number? 
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 01:11:29 AM
How can I convert these long integer values into negative numbers?

Please help

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: askm on February 01, 2008, 01:33:38 AM
You have not worked
with this in a
higher level language ?
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 01:48:03 AM
well I did not have to worry about this in high level language.

Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 01:51:08 AM
I did not have to display anything negative before
Title: Re: Quadratic Square Root Code Problem
Post by: Jimg on February 01, 2008, 02:38:03 AM
Ok, sorry I wasn't more explicit.  If you look at your code:

      Mov eax, numerator2
      IDiv denominator
      Mov realRoot2, eax       ; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)


You are doing a double word divide.  Look at the description for idiv.  It says:
Divides (signed) the value in the AL, AX, or EAX register by the source
operand and stores the result in the AX, DX:AX, or EDX:EAX registers.
The source operand can be a general-purpose register or a memory location.


Notice the notation  EDX:EAX

You need to convert the dword in eax to a qword in EDX:EAX before the division.


      Mov eax, numerator2
      cdq
      IDiv denominator
      Mov realRoot2, eax       ; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)

You have to be real careful about this stuff.

Also, in you last posting of your program, it starts:
.686 ; create 32 bit code

.Model flat, StdCall  ;32 bit memory model
Option CaseMap :none  ; case sensitive

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\include\macros.asm       ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

if you look at \masm32\include\masm32rt.inc
you will see it contains all the rest of the startup code, so delete everything else, or delete masm32rt.inc and add in what's missing.
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 01, 2008, 11:15:15 AM
Quote from: etow on February 01, 2008, 01:11:29 AM
How can I convert these long integer values into negative numbers?

Thanks

Hi etow,
             1. I dont know what is your doubt. I didnt understand. In any way

             2. In the Register of Flags there is a flag SIGN (SF).  If you have a number in EAX,
                 or    eax, eax  activate the sign flag.

             3. To get the digits of EAX, divide it successively by 10 and take the remainders in reverse
                 order. If the number is negative, put the sign - before.


              mov        ebx, 0                ; means the number is positive -> put sign + or not
              or           eax, eax
              jns          convert              ; jump if not sign
              ;
              mov         ebx, 1              ; means the number is negative -> put sign -
              neg         eax                   ; eax is positive
              ;
              ; convert positive EAX
              ;
convert:
 
               This help you ? Sorry if not
RuiLoureiro 
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 10:17:30 PM
Hi RuiLoureiro,
Thanks for your help
I got it to work.

Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 01, 2008, 10:39:14 PM
Hi

Does anyone know if there is a square root function for real or floating point numbers
that I could use to get real or floating point number results?
Also how do I display these results to a certain decimal point?

Here is my updated code below:

-----------------------------------------------------------------------------------------------

.686 ; create 32 bit code

.Model flat, StdCall  ;32 bit memory model
Option CaseMap :none  ; case sensitive

;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey        ; pause the screen while waiting for user to press any key
             ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proto:DWord, :DWord, :DWord

Main Proc
  Local WantContinue:DWord
  Local NumberA:DWord
  Local NumberB:DWord
  Local NumberC:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue to 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       Mov NumberA, sval(input("Enter an integer value for Number A : "))
       Mov NumberB, sval(input("Enter an integer value for Number B : "))
       Mov NumberC, sval(input("Enter an integer value for Number C : "))
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
    .EndW
  Ret
Main EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
  Local squareRootNumber:DWord
  Local negativeB:DWord
  Local resultOfSquareRoot:DWord
  Local numerator1:DWord
  Local numerator2:DWord
  Local denominator:DWord
  Local signedRoot1[1024]:Byte
  Local signedRoot2[1024]:Byte
  ; squareRootNumber is the square root part of the quadratic formula
  ; negativeB is the negation of b of the quadratic formula
  ; resultOfSquareRoot is the result after getting square root of number
  ;  of the quadratic formula
  ; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
  ;  to the quadratic formula
  ; numerator1 and numerator2 are the numerator part of the quadratic formula
  ;  that has two solutions
  ; denominator is the denominator of the quadratic formula

  ; Eax, Ebx, Ecx, Edx, Esi, Edi are registers

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

.If (A_Number != 0)      ; if A_Number is not equal to zero
    Mov Eax, B_Number     ; set Eax = B_Number
    Mov Edx, Eax          ; set Edx = Eax
    IMul Edx              ; Eax = Eax * Edx
    Mov Ebx, Eax          ; set Ebx = Eax
                          ; Ebx = b^2

    Mov Ecx, -4           ; set Ecx = -4
    Mov Eax, A_Number     ; set Eax = A_Number
    IMul C_Number         ; Eax = Eax * C_NUmber
    IMul Ecx              ; Eax = Eax * Ecx
                          ; Eax = -4 * a * c

    Add Ebx, Eax           ; Ebx = Ebx + Eax
    Mov squareRootNumber, Ebx  ; set squareRootNumber = Ebx
                               ; Ebx =  b^2 - 4 * a * c

   .If (squareRootNumber > SDWord Ptr - 1)
      Mov signedRoot1, 0                ; set signedRoot1 string array to empty
      Mov signedRoot2, 0                ; set signedRoot2 string array to empty

      Invoke IntSqrt, squareRootNumber   ; call square root function
      Mov resultOfSquareRoot, Eax        ; set resultOfSquareRoot = Eax

      Mov Eax, B_Number   ; set Eax = B_Number
      Neg Eax             ; Eax = Eax * -1
      Mov negativeB, Eax  ; set negativeB = Eax
                          ; Eax = -b

      Mov Eax, 2             ; set Eax = 2
      IMul A_Number          ; Eax = Eax * A_Number
      Mov denominator, Eax   ; set denominator = Eax
                             ;  Eax = 2 * a

      Mov Eax, negativeB     ; set Eax = negativeB
      Mov Ebx, resultOfSquareRoot  ; set Ebx = resultOfSquareRoot
      Add Eax, Ebx              ; Eax = Eax + Ebx
      Mov numerator1, Eax       ; set numerator1 = Eax
                                ;  Eax = (- b + sqrt(b^2 - 4 * a * c))

      Neg Ebx                   ; Ebx = Ebx * -1
                                ; - resultOfSquareRoot
      Mov Eax, negativeB        ; set Eax = negativeB
      Add Eax, Ebx              ; Eax = Eax + Ebx
      Mov numerator2, Eax       ; set numerator2 = Eax
                                ; Eax = (- b  - sqrt(b^2 - 4 * a * c))

      Mov Eax, numerator1       ; set Eax = numerator1
      Cdq                       ; convert to double quad word or 64-bit long word
      IDiv denominator          ; Eax = Eax / denominator
                                ; Eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)
      Mov Ebx, 0                ; number is positive
      Or Eax, Eax               ; activate sign flag
      Jns positive1             ; jump to positive1 label if positive number
      Mov Ebx, 1                ; number is negative
      Neg Eax                   ; Eax = Eax * -1
      Mov Esi, cat$(Addr signedRoot1, "-", str$(Eax)) ; concatenate negative sign
                                                      ; along with positive number
                                                      ; in Eax into signedRoot1
                                                      ; string array
      Jmp nextRoot              ; jump to nextRoot label

positive1:
      Mov Esi, cat$(Addr signedRoot1, str$(Eax)) ; concatenate positive number in
                                                 ; in Eax into signedRoot1 string
                                                 ; array
nextRoot:
      Mov Eax, numerator2        ; set Eax = numerator2
      Cdq                        ; convert to double quad word or 64-bit long word
      IDiv denominator           ; Eax = Eax / denominator
                                 ; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
      Mov Ebx, 0                 ; number is positive
      Or Eax, Eax                ; activate sign flag
      Jns positive2              ; jump to positive2 label if positive number
      Mov Ebx, 1                 ; number is negative
      Neg Eax                    ; Eax = Eax * -1
      Mov Edi, cat$(Addr signedRoot2, "-", str$(Eax)) ; concatenate negative sign
                                                      ; along with a positive number
                                                      ; in Eax into signedRoot2
                                                      ; string array
      Jmp output                 ; jump to output label

positive2:
      Mov Edi, cat$(Addr signedRoot2, str$(Eax)) ; concatenate positive number in
                                                 ; in Eax into signedRoot2 string
                                                 ; array
output:
      print chr$(13, 10)  ; a carriage return line feed will be outputted to the
                          ; screen
      print chr$(" Solutions for quadratic equation : ")

      ; The following if else statements output the format of the quadratic
      ; equation

      .If (A_Number == -1)  ; if A_Number equals to -1
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1) ; if A_Number equals to 1
        print chr$("X^2 ")
      .ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1)) ; if A_Number greater
                                                ; than 1 OR A_Number less than -1
        print str$(A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1) ; if B_Number less than -1
      print str$(B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1) ; if B_Number equals to -1
      print chr$("- X ")
      .ElseIf (B_Number == 1)  ; if B_Number equals to 1
      print chr$("+ X ")
      .ElseIf (B_Number > 1)   ; if B_Number greater than 1
      print chr$("+ ")
      print str$(B_Number)
        print chr$("X ")
      .EndIf

      .If (C_Number < SDWord Ptr - 1) ; if C_Number less than -1
        print str$(C_Number)
      .ElseIf (C_Number == -1)  ; if C_Number equals to -1
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0)  ; if C_Number greater than 0
      print chr$("+ ")
    print str$(C_Number)
      .EndIf

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print Addr signedRoot1   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print Addr signedRoot2  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

   .ElseIf (squareRootNumber <= SDWord Ptr - 1) ; if squareRootNumber less than or
                                                ; equal to -1
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following if else statements output the format of the quadratic
      ; equation

      .If (A_Number == -1)  ; if A_Number equals to -1
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1) ; if A_Number equals to 1
        print chr$("X^2 ")
      .ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1)) ; if A_Number greater
                                                ; than 1 OR A_Number less than -1
        print str$(A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1) ; if B_Number less than -1
      print str$(B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1) ; if B_Number equals to -1
      print chr$("- X ")
      .ElseIf (B_Number == 1)  ; if B_Number equals to 1
      print chr$("+ X ")
      .ElseIf (B_Number > 1)   ; if B_Number greater than 1
      print chr$("+ ")
      print str$(B_Number)
        print chr$("X ")
      .EndIf

      .If (C_Number < SDWord Ptr - 1) ; if C_Number less than -1
        print str$(C_Number)
      .ElseIf (C_Number == -1)  ; if C_Number equals to -1
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0)  ; if C_Number greater than 0
      print chr$("+ ")
    print str$(C_Number)
      .EndIf

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
   .EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10, 13, 10) ; if A_Number == 0
.EndIf
  Ret
calculateQuadraticRoots EndP

End start

Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 02, 2008, 12:26:07 AM
I want to know if there is a real or floating point  square root function?
Are there functions for the regular arithmetic functions such addition, subtraction, multiplication and division using real or floating point numbers?
If yes how do I declare them and use them?

Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 02, 2008, 01:10:08 AM
etow,

Yes, there are floating-point instructions that do all of that.

Take a look at Simply FPU (http://www.ray.masmcode.com/tutorial/index.html). It has everything you ever wanted to know about using the FPU.

Here (http://www.masm32.com/board/index.php?topic=7849.0) is a program I posted that makes extensive use of FPU.



Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 02, 2008, 12:06:46 PM
Quote from: etow on February 02, 2008, 12:26:07 AM
I want to know if there is a real or floating point  square root function?
Are there functions for the regular arithmetic functions such addition, subtraction, multiplication and division using real or floating point numbers?
If yes how do I declare them and use them?

Hi etow,
       
        1. Here an example to Add the variable RealNumberX with RealNumberY.
           The result goes to variable RealNumberZ. I have no experience in using
           this functions, but i think it is correct.

        2. Read the file fpulib in the folder masm32\help

        3. See all ASM files - other functions - in the folder masm32\fpulib

        4. Try and show to us your results.         
           

                ;**** we should include this files *****
                include    \masm32\fpulib\fpu.inc
                includelib \masm32\fpulib\fpu.lib
                ;***************************************
;.....................................................................
.data

RealNumberX     REAL10   5623.56786    ; save it in 10 bytes = 80 bits
RealNumberY     REAL10   -123.5678     ; save it in 10 bytes =  "
RealNumberZ     REAL10   ?             ; result in 10 bytes  =  "

;......................................................................
.code
   invoke  FpuAdd, offset  RealNumberX, offset  RealNumberY, offset  RealNumberZ,
                           SRC1_REAL or SRC2_REAL
       

Good work !
RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 03, 2008, 12:10:20 AM
To do the same thing directly using the FPU:


.DATA

    RealNumberX     REAL10   5623.56786    ; save it in 10 bytes = 80 bits
    RealNumberY     REAL10   -123.5678     ; save it in 10 bytes =  "
    RealNumberZ     REAL10   0.0           ; result in 10 bytes  =  "

.CODE

start:

    finit            ; Set the FPU to default settings, 64-bit precision,
                     ;  round to nearest etc.
    fld RealNumberX  ; Load RealNumberX to ST(0).
    fld RealNumberY  ; Load RealNumberY to ST(0), RealNumberX is now in ST(1).
    fadd             ; Add ST(0) to ST(1), store the result in ST(1),
                     ;  pop the stack, the result is now in ST(0).
    fstp RealNumberZ ; Store ST(0) to RealNumberZ and pop the stack.


Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 03, 2008, 11:28:17 AM
Hi Greg,
            Good. Thank you !

            By the way, after finit , fld   RealNumberX      ; Load RealNumberX to ST(0)
            and ST(0) is the register number 7 ( status word bits 13- 11 )  no ?

           fadd             ; Add ST(0) to ST(1), store the result in ST(1),
                              ;  pop the stack ?, the result is now in ST(0).

           I  know  faddp         ; add real and pop.  fadd does the same thing ?

            Thank you Greg.
Rui
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 03, 2008, 09:08:42 PM
Hi

My updated code below:

--------------------------------------------------------------------------

.686 ; create 32 bit code
.Model flat, StdCall  ;32 bit memory model
Option CaseMap :none  ; case sensitive

;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc


.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP


calculateQuadraticRoots Proto:Real8, :Real8, :Real8

Main Proc
  Local WantContinue:DWord
  Local NumberA:Real8
  Local NumberB:Real8
  Local NumberC:Real8
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue to 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter an integer value for Number A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter an integer value for Number B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter an integer value for Number C : ")
       Invoke InputR10, Addr NumberC
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
    .EndW
  Ret
Main EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real8, B_Number:Real8, C_Number:Real8
  Local squareRootNumber:Real8
   Local negativeB:Real8
   Local resultOfSquareRoot:Real8
   Local denominator:Real8
   Local signedRoot1:Real8
   Local signedRoot2:Real8
  ; squareRootNumber is the square root part of the quadratic formula
  ; negativeB is the negation of b of the quadratic formula
  ; resultOfSquareRoot is the result after getting square root of number
  ;  of the quadratic formula
  ; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
  ;  to the quadratic formula
  ; numerator1 and numerator2 are the numerator part of the quadratic formula
  ;  that has two solutions
  ; denominator is the denominator of the quadratic formula

  ; Eax, Ebx, Ecx, Edx, Esi, Edi are registers

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

.If (A_Number != 0.0)      ; if A_Number is not equal to zero

    Fld (A_Number)     ; st(0) = A_Number
    Fld (C_Number)     ; st(0) = C_Number , st(1) = A_Number
    Fmulp St(1), St    ; st(1) = st(1) * st(0) = A_Number * C_Number
    Fld (-4.0)         ; st(0) = -4.0 , st(1) = A_Number * C_Number
    Fmulp St(1), St    ; st(1) = st(1) * st(0) = A_Number * C_Number * -4.0
    Fld (B_Number)     ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
    Fmul St, St        ; st(0) = st(0) * st(0) = B_Number * B_Number
    Faddp St(1), St    ; st(1) = st(1) + st(0)
                       ;       = A_Number * C_Number * -4.0 + B_Number * B_Number
    Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)

   .If (squareRootNumber > SDWord Ptr - 1.0) ; if squareRootNumber > -1.0
      Fsqrt                                 ; Sqrt st(0)
      Fstp resultOfSquareRoot      ; resultOfSquareRoot = sqrt st(0)
      Fld (B_Number)                  ; st(0) = B_Number
      Fchs                                 ; st(0) = -B_Number
      Fstp negativeB                  ; negativeB = st(0)
      Fld negativeB                    ; st(0) = negativeB
      Fld resultOfSquareRoot       ; st(0) = resultOfSquareRoot , st(1) = negativeB
      Faddp St(1), St                 ; st(1) = st(1) + st(0) = negativeB + resultOfSquareRoot
      Fstp numerator1               ; numerator1  = st(0)
      Fld (A_Number)                ; st(0) = A_Number     
      Fld (2.0)                          ; st(0) = 2.0 , st(1) = A_Number
      Fmulp St(1), St                ; st(1) = st(1) * st(0) = A_Number * 2.0
      Fstp denominator             ; denominator = st(0)
      Fld (numerator1)            ; st(0) = numerator1
      Fld (denominator)             ; st(0) = denominator , st(1) numerator1
      Fdivp St(1), St                ; st(1) = st(1) / st(0) = numerator1 / denominator
      Fstp signedRoot1            ; signedRoot1 = st(1) = numerator1 / denominator

      Fld negativeB                ;   st(0) = negativeB
      Fld resultOfSquareRoot  ;    st(0) = resultOfSquareRoot , st(1) = negativeB
      Fchs                           ;    st(0) = -resultOfSquareRoot
      Faddp St(1), St            ;    st(1) = st(1) + st(0) = negativeB + -resultOfSquareRoot
      Fld denominator           ;    st(0) = denominator , st(1) = negativeB + resultOfSquareRoot
      Fdivp St(1), St            ;    st(1) = st(1) / st(0) = (negativeB + resultOfSquareRoot) / denominator
      Fstp signedRoot2        ;    signedRoot2 = st(1)

      print chr$(13, 10)  ; a carriage return line feed will be outputted to the
                          ; screen
      print chr$(" Solutions for quadratic equation : ")

      ; The following if else statements output the format of the quadratic
      ; equation

      .If (A_Number == -1.0)  ; if A_Number equals to -1.0
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1.0) ; if A_Number equals to 1.0
        print chr$("X^2 ")
      .ElseIf ((A_Number > 1.0) || (A_Number < SDWord Ptr - 1.0))
      ; if A_Number greater than 1.0 Or A_Number less than - 1.0
        print real8$ (A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1.0) ; if B_Number less than -1.0
      print real8$ (B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1.0) ; if B_Number equals to -1.0
      print chr$("- X ")
      .ElseIf (B_Number == 1.0)  ; if B_Number equals to 1.0
      print chr$("+ X ")
      .ElseIf (B_Number > 1.0)   ; if B_Number greater than 1.0
      print chr$("+ ")
      print real8$ (B_Number)
        print chr$("X ")
      .EndIf

      .If (C_Number < SDWord Ptr - 1.0) ; if C_Number less than -1.0
        print real8$ (C_Number)
      .ElseIf (C_Number == -1.0)  ; if C_Number equals to -1.0
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0.0)  ; if C_Number greater than 0.0
      print chr$("+ ")
    print real8$ (C_Number)
      .EndIf

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real8$ (signedRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real8$ (signedRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

   .ElseIf (squareRootNumber <= SDWord Ptr - 1.0) ;
      ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following if else statements output the format of the quadratic
      ; equation

      .If (A_Number == -1.0)  ; if A_Number equals to -1.0
      print chr$("-X^2 ")
      .ElseIf (A_Number == 1.0) ; if A_Number equals to 1.0
        print chr$("X^2 ")
      .ElseIf ((A_Number > 1.0) || (A_Number < SDWord Ptr - 1.0))
      ; if A_Number greater than 1.0 OR A_Number less than -1.0
        print real8$ (A_Number)
        print chr$("X^2 ")
      .EndIf

      .If (B_Number < SDWord Ptr - 1.0) ; if B_Number less than -1.0
      print real8$ (B_Number)
      print chr$("X ")
      .ElseIf (B_Number == -1.0) ; if B_Number equals to -1.0
      print chr$("- X ")
      .ElseIf (B_Number == 1.0)  ; if B_Number equals to 1.0
      print chr$("+ X ")
      .ElseIf (B_Number > 1.0)   ; if B_Number greater than 1.0
      print chr$("+ ")
      print real8$ (B_Number)
        print chr$("X ")
      .EndIf

      .If (C_Number < SDWord Ptr - 1.0) ; if C_Number less than -1.0
        print real8$ (C_Number)
      .ElseIf (C_Number == -1.0)  ; if C_Number equals to -1.0
      print chr$("- ")
        print chr$("1")
      .ElseIf (C_Number > 0.0)  ; if C_Number greater than 0.0
      print chr$("+ ")
    print real8$ (C_Number)
      .EndIf

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
   .EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10, 13, 10) ; if A_Number == 0
.EndIf
  Ret
calculateQuadraticRoots EndP

End start


----------------------------------------------------------------------------------------
The following are my debug error messages:

============== QuadraticSolutions - Debug ==============

Assembling: Module1
Module1.asm(2) : warning A4011: multiple .MODEL directives found : .MODEL ignored
\masm32\include\masm32rt.inc(33) : warning A4011: multiple .MODEL directives found : .MODEL ignored
------------------------------------------
WARNING Duplicate include file windows.inc
------------------------------------------
-----------------------------------------
WARNING Duplicate include file user32.inc
-----------------------------------------
-----------------------------------------
WARNING Duplicate include file kernel32.inc
-----------------------------------------
Module1.asm(91) : error A2050: real or BCD number not allowed
Module1.asm(96) : error A2009: syntax error in expression
Module1.asm(104) : error A2009: syntax error in expression
Module1.asm(112) : error A2050: real or BCD number not allowed
Module1.asm(133) : error A2050: real or BCD number not allowed
Module1.asm(135) : error A2050: real or BCD number not allowed
Module1.asm(137) : error A2050: real or BCD number not allowed
Module1.asm(137) : error A2009: syntax error in expression
Module1.asm(143) : error A2009: syntax error in expression
Module1.asm(146) : error A2050: real or BCD number not allowed
Module1.asm(148) : error A2050: real or BCD number not allowed
Module1.asm(150) : error A2050: real or BCD number not allowed
Module1.asm(156) : error A2009: syntax error in expression
Module1.asm(158) : error A2050: real or BCD number not allowed
Module1.asm(161) : error A2050: real or BCD number not allowed
Module1.asm(178) : error A2009: syntax error in expression
Module1.asm(186) : error A2050: real or BCD number not allowed
Module1.asm(188) : error A2050: real or BCD number not allowed
Module1.asm(190) : error A2050: real or BCD number not allowed
Module1.asm(190) : error A2009: syntax error in expression
Module1.asm(196) : error A2009: syntax error in expression
Module1.asm(199) : error A2050: real or BCD number not allowed
Module1.asm(201) : error A2050: real or BCD number not allowed
Module1.asm(203) : error A2050: real or BCD number not allowed
Module1.asm(209) : error A2009: syntax error in expression
Module1.asm(211) : error A2050: real or BCD number not allowed
Module1.asm(214) : error A2050: real or BCD number not allowed

Errors ocurred.
--------------------------------------------------------------------

How do I solve these error messages with comparision run time operators related to integers that can be used for floating point or real numbers and floating point instructions.

Please help me.

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 03, 2008, 10:29:44 PM
etow,

You need to go back and read what people have told you, more than once, about include files. Take a look at what 'masm32rt.inc' contains. Whatever it contains does not need to be included in your code again.

You cannot use real numbers with the MASM high-level directives like .IF. To compare real numbers you must use an FPU instruction like FCOM. Read about FCOM in SimplyFPU, there is example code too.

Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 03, 2008, 10:40:21 PM
Hi etow,
            1. It is too hard to follow, yet.

            2. I think you cannot load constants like  *** fld     -4   ***, ***  fld    2 ****

            3. To calculate 2a:   fld          A_Number
                                         fld          st(0)              ; copy to new st(0)
                                         fadd                            ; st0= 2a

            4. To test b^2-4ac:
                                            ftst           
                                            fwait
                                            fstsw   ax

            5.  Why not to use global variables ?
                 .DATA
                  Number4       REAL10   4.0                 then        fld     Number4

            6. Cannot you divide calculateQuadraticRoots in such a way that it only calculate
                signedRoot1 and signedRoot2 ? It can exit with EAX = 0 meaning OK, EAX=1 -> error
                EAX= 2 ... etc. Put the other things in another proc if you can

            7. Cannot you test A_Number before calling calculateQuadraticRoots ? You dont call if
                 it is 0.

            8. You can calculate Root1 and Root2 without using local variables. FPU has 8 registers and
                you can use it. Think about this. How to use them better


RuiLoureiro

Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 03, 2008, 11:10:46 PM
Quote from: RuiLoureiro2. I think you cannot load constants like  *** fld     -4   ***, ***  fld    2 ****

That's right, you can't.

There are some MASM32 macros for doing this called FP4, FP8 and FP10. Also see the fld4, fld8 and fld10 macros.


fld FP10(5.5)
fld FP10(2.5)

fld10 5.5
fld10 2.5


Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 04, 2008, 12:11:11 AM
Some macros I wrote for comparing real numbers:


; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================


Usage:


.IF isgreater(r1, r2)
    ...
.ENDIF


Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 04, 2008, 01:44:14 PM
Hi Greg,

for example in one of your macros isgreater than what is REQ data type means for r1 and r2
Can you use for example do this?,

                                      .If isgreater(st(0),-1.0)
                                            ....
                                      .Endif



Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 04, 2008, 01:53:00 PM
hi Greg,

Can you do this,

.If isgreater(Real10 Ptr [Eax],-1.0)
  ....
.Endif
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 04, 2008, 03:11:07 PM
Here is my updated code below:


.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib

.Data
Number2  Real10  2.0
NumberNegative4 Real10 - 4.0

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP


; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================


calculateQuadraticRoots Proto:Ptr Real10, Ptr Real10, Ptr Real10
printFormat Proto:Ptr Real10, Ptr Real10, Ptr Real10

Main Proc
  Local WantContinue:DWord
  Local NumberA:Real10
  Local NumberB:Real10
  Local NumberC:Real10
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue to 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter an integer value for Number A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter an integer value for Number B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter an integer value for Number C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(Addr NumberA, 0.0) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, Addr NumberA, Addr NumberB, Addr NumberC
       print chr$(13, 10)
     .ElseIf isequal(Addr NumberA, 0.0)
    print chr$(13, 10)
    print chr$("Error, Division by zero!", 13, 10, 13, 10) ; if NumberA == 0
     .EndIf
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
    .EndW
  Ret
Main EndP

printFormat Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
    Mov Eax, A_Number
    Mov Ebx, B_Number
    Mov Ecx, C_Number

    .If isequal(Real10 Ptr [Eax], -1.0)
    ; if A_Number equals to -1.0
     print chr$("-X^2 ")
    .ElseIf isequal(Real10 Ptr [Eax], 1.0)
     ; if A_Number equals to 1.0
       print chr$("X^2 ")
    .ElseIf (isgreater(Real10 Ptr [Eax], 1.0) || islessthan (Real10 Ptr [Eax, -1.0))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       print real10$ (A_Number)
       print chr$("X^2 ")
    .EndIf

    .If isless(Real10 Ptr [Ebx], -1.0)
    ; if B_Number less than -1.0
       print real10$ (B_Number)
       print chr$("X ")
    .ElseIf isequal(Real10 Ptr [Ebx], -1.0)
    ; if B_Number equals to -1.0
       print chr$("- X ")
    .ElseIf isequal(Real10 Ptr [Ebx], 1.0)
    ; if B_Number equals to 1.0
       print chr$("+ X ")
    .ElseIf isgreater(Real10 Ptr [Ebx], 1.0)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       print real10$ (B_Number)
       print chr$("X ")
    .EndIf

    .If isless(Real10 Ptr [Ecx], -1.0)
    ; if C_Number less than -1.0
       print real10$ (C_Number)
    .ElseIf isequal(Real10 Ptr [Ecx], -1.0)
    ; if C_Number equals to -1.0
       print chr$("- ")
       print chr$("1")
    .ElseIf isgreater(Real10 Ptr [Ecx], 0.0)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       print real10$ (C_Number)
    .EndIf

Ret
printFormat EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
   Local squareRootNumber:Real10
   Local negativeB:Real10
   Local resultOfSquareRoot:Real10
   Local numerator1:Real10
   Local denominator:Real10
   Local signedRoot1:Real10
   Local signedRoot2:Real10
  ; squareRootNumber is the square root part of the quadratic formula
  ; negativeB is the negation of b of the quadratic formula
  ; resultOfSquareRoot is the result after getting square root of number
  ;  of the quadratic formula
  ; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
  ;  to the quadratic formula
  ; numerator1 and numerator2 are the numerator part of the quadratic formula
  ;  that has two solutions
  ; denominator is the denominator of the quadratic formula

  ; Eax, Ebx, Ecx, Edx are registers
  ; St(i) are Fpu registers

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

   Mov Eax, A_Number
   Mov Ebx, B_Number
   Mov Ecx, C_Number

   Fld Real10 Ptr [Eax] ; st(0) = A_Number
   Fld Real10 Ptr [Ecx] ; st(0) = C_Number , st(1) = A_Number
   Fmulp St(1), St    ; st(1) = st(1) * st(0) = A_Number * C_Number
   Fld (NumberNegative4) ; st(0) = -4.0 , st(1) = A_Number * C_Number
   Fmulp St(1), St    ; st(1) = st(1) * st(0) = A_Number * C_Number * -4.0
   Fld Real10 Ptr [Ebx] ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
   Fmul St, St        ; st(0) = st(0) * st(0) = B_Number * B_Number
   Faddp St(1), St ; st(1) = st(1) + st(0)
                   ;       = A_Number * C_Number * -4.0 + B_Number * B_Number
   Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)

   Fld squareRootNumber  ; st(0) = squareRootNumber

   .If isgreater(squareRootNumber, -1.0)
      ; if squareRootNumber greater than -1.0
      Fsqrt                   ; Sqrt st(0)
      Fstp resultOfSquareRoot ; resultOfSquareRoot = sqrt st(0)
      Fld Real10 Ptr [Ebx]    ; st(0) = B_Number
      Fchs                    ; st(0) = -B_Number
      Fstp negativeB          ; negativeB = st(0)
      Fld negativeB          ; st(0) = negativeB
      Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
      Faddp St(1), St        ; st(1) = st(1) + st(0) = negativeB + resultOfSquareRoot
      Fstp numerator1        ; numerator1  = st(0)
      Fld Real10 Ptr [Eax]   ; st(0) = A_Number
      Fld (Number2)          ; st(0) = 2.0 , st(1) = A_Number
      Fmulp St(1), St        ; st(1) = st(1) * st(0) = A_Number * 2.0
      Fstp denominator       ; denominator = st(0)
      Fld (numerator1)       ; st(0) = numerator1
      Fld (denominator)      ; st(0) = denominator , st(1) numerator1
      Fdivp St(1), St        ; st(1) = st(1) / st(0) = numerator1 / denominator
      Fstp signedRoot1       ; signedRoot1 = st(1) = numerator1 / denominator

      Ffree St(0)
      Fld negativeB           ; st(0) = negativeB
      Fld resultOfSquareRoot  ; st(0) = resultOfSquareRoot , st(1) = negativeB
      Fchs                    ; st(0) = -resultOfSquareRoot
      Faddp St(1), St         ; st(1) = st(1) + st(0) = negativeB + -resultOfSquareRoot
      Fld denominator         ; st(0) = denominator , st(1) = negativeB + resultOfSquareRoot
      Fdivp St(1), St         ; st(1) = st(1) / st(0) = (negativeB + resultOfSquareRoot) / denominator
      Fstp signedRoot2        ; signedRoot2 = st(1)

      print chr$(13, 10)  ; a carriage return line feed will be outputted to the
                          ; screen
      print chr$(" Solutions for quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printFormat, Addr A_Number, Addr B_Number, Addr C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (signedRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (signedRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

    .ElseIf islessequal(squareRootNumber, -1.0)
      ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printFormat, Addr A_Number, Addr B_Number, Addr C_Number

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
   .EndIf
  Ret
calculateQuadraticRoots EndP

End start

-------------------------------------------------------------------

Here are my debugger error messages below:

============== QuadraticSolutions - Debug ==============

Module1.asm(217) : error A2008: syntax error : ptr
Module1.asm(218) : error A2008: syntax error : ptr
Module1.asm(244) : error A2008: syntax error : Addr
isnotequal(4): Macro Called From
  Module1.asm(244): Include File
Module1.asm(247) : error A2008: syntax error : Addr
isequal(4): Macro Called From
  Module1.asm(247): Include File
Module1.asm(268) : error A2008: syntax error : ,
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
Module1.asm(243) : error A2050: real or BCD number not allowed
isnotequal(3): Macro Called From
  Module1.asm(243): Include File
Module1.asm(246) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(246): Include File
Module1.asm(261) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(261): Include File
Module1.asm(264) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(264): Include File
Module1.asm(267) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(267): Include File
Module1.asm(273) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(273): Include File
Module1.asm(277) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(277): Include File
Module1.asm(280) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(280): Include File
Module1.asm(283) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(283): Include File
Module1.asm(290) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(290): Include File
Module1.asm(293) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(293): Include File
Module1.asm(297) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(297): Include File
Module1.asm(352) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(352): Include File
Module1.asm(402) : error A2050: real or BCD number not allowed
islessequal(3): Macro Called From
  Module1.asm(402): Include File
Module1.asm(270) : error A2052: forced error
real10$(14): Macro Called From
  print(0): Macro Called From
   Module1.asm(270): Include File
Module1.asm(276) : error A2052: forced error
real10$(12): Macro Called From
  print(0): Macro Called From
   Module1.asm(276): Include File
Module1.asm(287) : error A2052: forced error
real10$(12): Macro Called From
  print(0): Macro Called From
   Module1.asm(287): Include File
Module1.asm(293) : error A2052: forced error
real10$(12): Macro Called From
  print(0): Macro Called From
   Module1.asm(293): Include File
Module1.asm(301) : error A2052: forced error
real10$(12): Macro Called From
  print(0): Macro Called From
   Module1.asm(301): Include File

Errors ocurred.
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 04, 2008, 03:38:07 PM
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib

.Data
Number2  Real10  2.0
NumberNegative4 Real10 - 4.0

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP


; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================


calculateQuadraticRoots Proto:Ptr Real10, Ptr Real10, Ptr Real10
printFormat Proto:Ptr Real10, Ptr Real10, Ptr Real10

Main Proc
  Local WantContinue:DWord
  Local NumberA:Real10
  Local NumberB:Real10
  Local NumberC:Real10
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue to 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter an integer value for Number A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter an integer value for Number B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter an integer value for Number C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(Addr NumberA, 0.0) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, Addr NumberA, Addr NumberB, Addr NumberC
       print chr$(13, 10)
     .ElseIf isequal(Addr NumberA, 0.0) ; if NumberA == 0.0
       print chr$(13, 10)
       print chr$("Error, Division by zero!", 13, 10, 13, 10)
     .EndIf
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

       Mov counter, 0
       .While counter <= 8
            Ffree St (counter)
            Inc counter
       .EndW

    .EndW
  Ret
Main EndP

printFormat Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
    Mov Eax, A_Number
    Mov Ebx, B_Number
    Mov Ecx, C_Number

    Fld Real10 Ptr [Eax]
    .If isequal(St(0), -1.0)
    ; if A_Number equals to -1.0
        print chr$("-X^2 ")
    .ElseIf isequal(St(0), 1.0)
     ; if A_Number equals to 1.0
       print chr$("X^2 ")
    .ElseIf (isgreater(St(0), 1.0) || islessthan (St(0), -1.0))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       print real10$ (A_Number)
       print chr$("X^2 ")
    .EndIf

    Fld Real10 Ptr [Ebx]

    .If isless(St(0), -1.0)
    ; if B_Number less than -1.0
       print real10$ (B_Number)
       print chr$("X ")
    .ElseIf isequal(St(0), -1.0)
    ; if B_Number equals to -1.0
       print chr$("- X ")
    .ElseIf isequal(St(0), 1.0)
      ; if B_Number equals to 1.0
       print chr$("+ X ")
    .ElseIf isgreater(St(0), 1.0)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       print real10$ (B_Number)
       print chr$("X ")
    .EndIf

    Fld Real10 Ptr [Ecx]

    .If isless(St(0), -1.0)
    ; if C_Number less than -1.0
       print real10$ (C_Number)
    .ElseIf isequal(St(0), -1.0)
    ; if C_Number equals to -1.0
       print chr$("- ")
       print chr$("1")
    .ElseIf isgreater(St(0), 0.0)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       print real10$ (C_Number)
    .EndIf

   Ret
printFormat EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
   Local squareRootNumber:Real10
   Local negativeB:Real10
   Local resultOfSquareRoot:Real10
   Local numerator1:Real10
   Local denominator:Real10
   Local signedRoot1:Real10
   Local signedRoot2:Real10
  ; squareRootNumber is the square root part of the quadratic formula
  ; negativeB is the negation of b of the quadratic formula
  ; resultOfSquareRoot is the result after getting square root of number
  ;  of the quadratic formula
  ; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
  ;  to the quadratic formula
  ; numerator1 is the numerator part of the quadratic formula
  ;  that has two solutions
  ; denominator is the denominator of the quadratic formula

  ; Eax, Ebx, Ecx, Edx are registers
  ; St(i) are Fpu registers

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

   Mov Eax, A_Number
   Mov Ebx, B_Number
   Mov Ecx, C_Number

   Finit

   Fld Real10 Ptr [Eax] ; st(0) = A_Number
   Fld Real10 Ptr [Ecx] ; st(0) = C_Number , st(1) = A_Number
   Fmulp St(1), St    ; st(1) = st(1) * st(0)
                      ;        = A_Number * C_Number
   Fld (NumberNegative4) ; st(0) = -4.0 , st(1) = A_Number * C_Number
   Fmulp St(1), St    ; st(1) = st(1) * st(0)
                      ;        = A_Number * C_Number * -4.0
   Fld Real10 Ptr [Ebx] ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
   Fmul St, St        ; st(0) = st(0) * st(0)
                      ;       = B_Number * B_Number
   Faddp St(1), St ; st(1) = st(1) + st(0)
                   ;       = A_Number * C_Number * -4.0 + B_Number * B_Number
   Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)

   Fld squareRootNumber  ; st(0) = squareRootNumber

   .If isgreater(squareRootNumber, -1.0)
      ; if squareRootNumber greater than -1.0
      Fsqrt                   ; Sqrt st(0)
      Fstp resultOfSquareRoot ; resultOfSquareRoot = sqrt st(0)
      Fld Real10 Ptr [Ebx]    ; st(0) = B_Number
      Fchs                    ; st(0) = -B_Number
      Fstp negativeB          ; negativeB = st(0)
      Fld negativeB          ; st(0) = negativeB
      Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
      Faddp St(1), St        ; st(1) = st(1) + st(0)
                             ;       = negativeB + resultOfSquareRoot
      Fstp numerator1        ; numerator1  = st(0)
      Fld Real10 Ptr [Eax]   ; st(0) = A_Number
      Fld (Number2)          ; st(0) = 2.0 , st(1) = A_Number
      Fmulp St(1), St        ; st(1) = st(1) * st(0)
                             ;       = A_Number * 2.0
      Fstp denominator       ; denominator = st(0)
      Fld (numerator1)       ; st(0) = numerator1
      Fld (denominator)      ; st(0) = denominator , st(1) numerator1
      Fdivp St(1), St        ; st(1) = st(1) / st(0)
                             ;       = numerator1 / denominator
      Fstp signedRoot1       ; signedRoot1 = st(1) = numerator1 / denominator

      Ffree St(0)
      Fld negativeB           ; st(0) = negativeB
      Fld resultOfSquareRoot  ; st(0) = resultOfSquareRoot , st(1) = negativeB
      Fchs                    ; st(0) = -resultOfSquareRoot
      Faddp St(1), St         ; st(1) = st(1) + st(0)
                              ;       = negativeB + -resultOfSquareRoot
      Fld denominator         ; st(0) = denominator , st(1) = negativeB + -resultOfSquareRoot
      Fdivp St(1), St         ; st(1) = st(1) / st(0)
                              ;       = (negativeB + -resultOfSquareRoot) / denominator
      Fstp signedRoot2        ; signedRoot2 = st(1)

      print chr$(13, 10)  ; a carriage return line feed will be outputted to the
                          ; screen
      print chr$(" Solutions for quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printFormat, Addr A_Number, Addr B_Number, Addr C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (signedRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (signedRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

    .ElseIf islessequal(squareRootNumber, -1.0)
        ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printFormat, Addr A_Number, Addr B_Number, Addr C_Number

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
   .EndIf
  Ret
calculateQuadraticRoots EndP

End start
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 05, 2008, 01:26:02 AM
Hi

Here is my updated code below:


.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib

.Data
Number2  Real10  2.0
NumberNegative4 Real10 - 4.0

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================

printQuadraticFormat Proto:Real10, Real10, Real10
calculateQuadraticRoots Proto:Real10, Real10, Real10


Main Proc
  Local WantContinue:DWord
  Local NumberA:Real10
  Local NumberB:Real10
  Local NumberC:Real10
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue to 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real value for Number A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real value for Number B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real value for Number C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(NumberA, 0.0) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
     .ElseIf isequal(NumberA, 0.0) ; if NumberA == 0.0
    print chr$(13, 10)
    print chr$("Error, Division by zero!", 13, 10, 13, 10)
     .EndIf
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

       Mov counter, 0
       .While counter <= 8
          Ffree St (counter)
          Inc counter
       .EndW

    .EndW
  Ret
Main EndP

printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10
    Mov Eax, A_Number
    Mov Ebx, B_Number
    Mov Ecx, C_Number

    Fld Real10 Ptr [Eax]

    .If isequal(St(0), -1.0)
    ; if A_Number equals to -1.0
     print chr$("-X^2 ")
    .ElseIf isequal(St(0), 1.0)
     ; if A_Number equals to 1.0
       print chr$("X^2 ")
    .ElseIf (isgreater(St(0), 1.0) || isless(St(0), -1.0))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       print real10$ (St(0))
       print chr$("X^2 ")
    .EndIf

    Fld Real10 Ptr [Ebx]

    .If isless(St(0), -1.0)
    ; if B_Number less than -1.0
       print real10$ (St(0))
       print chr$("X ")
    .ElseIf isequal(St(0), -1.0)
    ; if B_Number equals to -1.0
       print chr$("- X ")
    .ElseIf isequal(St(0), 1.0)
    ; if B_Number equals to 1.0
       print chr$("+ X ")
    .ElseIf isgreater(St(0), 1.0)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       print real10$ (St(0))
       print chr$("X ")
    .EndIf

    Fld Real10 Ptr [Ecx]

    .If isless(St(0), -1.0)
    ; if C_Number less than -1.0
       print real10$ (St(0))
    .ElseIf isequal(St(0), -1.0)
    ; if C_Number equals to -1.0
       print chr$("- ")
       print chr$("1")
    .ElseIf isgreater(St(0), 0.0)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       print real10$ (St(0))
    .EndIf

Ret
printQuadraticFormat EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real10, B_Number:Real10, C_Number:Real10
   Local squareRootNumber:Real10
   Local negativeB:Real10
   Local resultOfSquareRoot:Real10
   Local numerator1:Real10
   Local denominator:Real10
   Local signedRoot1:Real10
   Local signedRoot2:Real10
  ; squareRootNumber is the square root part of the quadratic formula
  ; negativeB is the negation of b of the quadratic formula
  ; resultOfSquareRoot is the result after getting square root of number
  ;  of the quadratic formula
  ; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
  ;  to the quadratic formula
  ; numerator1 is the numerator part of the quadratic formula
  ;  that has two solutions
  ; denominator is the denominator of the quadratic formula

  ; Eax, Ebx, Ecx, Edx are registers
  ; St(i) are Fpu registers

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

   Mov Eax, A_Number
   Mov Ebx, B_Number
   Mov Ecx, C_Number

   Finit

   Fld Real10 Ptr [Eax] ; st(0) = A_Number
   Fld Real10 Ptr [Ecx] ; st(0) = C_Number , st(1) = A_Number
   Fmulp St(1), St    ; st(1) = st(1) * st(0)
                      ;       = A_Number * C_Number
   Fld (NumberNegative4) ; st(0) = -4.0 , st(1) = A_Number * C_Number
   Fmulp St(1), St    ; st(1) = st(1) * st(0)
                      ;       = A_Number * C_Number * -4.0
   Fld Real10 Ptr [Ebx] ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
   Fmul St, St        ; st(0) = st(0) * st(0)
                      ;       = B_Number * B_Number
   Faddp St(1), St ; st(1) = st(1) + st(0)
                   ;       = A_Number * C_Number * -4.0 + B_Number * B_Number
   Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)

   Fld squareRootNumber  ; st(0) = squareRootNumber

   .If isgreater(squareRootNumber, -1.0)
      ; if squareRootNumber greater than -1.0
      Fsqrt                   ; Sqrt st(0)
      Fstp resultOfSquareRoot ; resultOfSquareRoot = sqrt st(0)
      Fld Real10 Ptr [Ebx]    ; st(0) = B_Number
      Fchs                    ; st(0) = -B_Number
      Fstp negativeB          ; negativeB = st(0)
      Fld negativeB          ; st(0) = negativeB
      Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
      Faddp St(1), St        ; st(1) = st(1) + st(0)
                             ;       = negativeB + resultOfSquareRoot
      Fstp numerator1        ; numerator1  = st(0)
      Fld Real10 Ptr [Eax]   ; st(0) = A_Number
      Fld (Number2)          ; st(0) = 2.0 , st(1) = A_Number
      Fmulp St(1), St        ; st(1) = st(1) * st(0)
                             ;       = A_Number * 2.0
      Fstp denominator       ; denominator = st(0)
      Fld (numerator1)       ; st(0) = numerator1
      Fld (denominator)      ; st(0) = denominator , st(1) numerator1
      Fdivp St(1), St        ; st(1) = st(1) / st(0)
                             ;       = numerator1 / denominator
      Fstp signedRoot1       ; signedRoot1 = st(1) = numerator1 / denominator

      Ffree St(0)
      Fld negativeB           ; st(0) = negativeB
      Fld resultOfSquareRoot  ; st(0) = resultOfSquareRoot , st(1) = negativeB
      Fchs                    ; st(0) = -resultOfSquareRoot
      Faddp St(1), St         ; st(1) = st(1) + st(0)
                              ;       = negativeB + -resultOfSquareRoot
      Fld denominator         ; st(0) = denominator , st(1) = negativeB + -resultOfSquareRoot
      Fdivp St(1), St         ; st(1) = st(1) / st(0)
                              ;       = (negativeB + -resultOfSquareRoot) / denominator
      Fstp signedRoot2        ; signedRoot2 = st(1)

      print chr$(13, 10)  ; a carriage return line feed will be outputted to the
                          ; screen
      print chr$(" Solutions for quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation
      Mov A_Number, Eax
      Mov B_Number, Ebx
      Mov C_Number, Ecx

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (signedRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (signedRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

    .ElseIf islessequal(squareRootNumber, -1.0)
      ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation
      Mov A_Number, Eax
      Mov B_Number, Ebx
      Mov C_Number, Ecx

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number
      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
   .EndIf
  Ret

calculateQuadraticRoots EndP

End start


-------------------------------------------------------------------------------------------
Here are my debugger error messages below:

Module1.asm(215) : error A2008: syntax error : real10
Module1.asm(216) : error A2008: syntax error : real10
Module1.asm(265) : error A2070: invalid instruction operands
Module1.asm(266) : error A2070: invalid instruction operands
Module1.asm(267) : error A2070: invalid instruction operands
Module1.asm(349) : error A2070: invalid instruction operands
Module1.asm(350) : error A2070: invalid instruction operands
Module1.asm(351) : error A2070: invalid instruction operands
Module1.asm(411) : error A2070: invalid instruction operands
Module1.asm(412) : error A2070: invalid instruction operands
Module1.asm(413) : error A2070: invalid instruction operands
Module1.asm(436) : error A2070: invalid instruction operands
Module1.asm(437) : error A2070: invalid instruction operands
Module1.asm(438) : error A2070: invalid instruction operands
Module1.asm(243) : error A2050: real or BCD number not allowed
isnotequal(3): Macro Called From
  Module1.asm(243): Include File
Module1.asm(246) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(246): Include File
Module1.asm(256) : error A2115: invalid coprocessor register
Module1.asm(270) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(270): Include File
Module1.asm(273) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(273): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(276): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(276): Include File
Module1.asm(284) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(284): Include File
Module1.asm(288) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(288): Include File
Module1.asm(291) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(291): Include File
Module1.asm(294) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(294): Include File
Module1.asm(303) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(303): Include File
Module1.asm(306) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(306): Include File
Module1.asm(310) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(310): Include File
Module1.asm(370) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(370): Include File
Module1.asm(428) : error A2050: real or BCD number not allowed
islessequal(3): Macro Called From
  Module1.asm(428): Include File

Errors ocurred.

-----------------------------------------------------------------------------------------------------------------------
I don't understand what these error messages mean.  I just know where the error messages occur at.  Please help me.


Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: MichaelW on February 05, 2008, 02:44:50 AM

Module1.asm(215) : error A2008: syntax error : real10
Module1.asm(216) : error A2008: syntax error : real10

; The correct syntax is Proto :Real10, :Real10, :Real10

Module1.asm(265) : error A2070: invalid instruction operands
Module1.asm(266) : error A2070: invalid instruction operands
Module1.asm(267) : error A2070: invalid instruction operands
Module1.asm(349) : error A2070: invalid instruction operands
Module1.asm(350) : error A2070: invalid instruction operands
Module1.asm(351) : error A2070: invalid instruction operands
Module1.asm(411) : error A2070: invalid instruction operands
Module1.asm(412) : error A2070: invalid instruction operands
Module1.asm(413) : error A2070: invalid instruction operands
Module1.asm(436) : error A2070: invalid instruction operands
Module1.asm(437) : error A2070: invalid instruction operands
Module1.asm(438) : error A2070: invalid instruction operands

; An 80-bit real10 will not fit in a 32-bit register.

Module1.asm(243) : error A2050: real or BCD number not allowed
isnotequal(3): Macro Called From
  Module1.asm(243): Include File
Module1.asm(246) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(246): Include File
Module1.asm(270) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(270): Include File
Module1.asm(273) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(273): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(276): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(276): Include File
Module1.asm(284) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(284): Include File
Module1.asm(288) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(288): Include File
Module1.asm(291) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(291): Include File
Module1.asm(294) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(294): Include File
Module1.asm(303) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
  Module1.asm(303): Include File
Module1.asm(306) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
  Module1.asm(306): Include File
Module1.asm(310) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(310): Include File
Module1.asm(370) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
  Module1.asm(370): Include File
Module1.asm(428) : error A2050: real or BCD number not allowed
islessequal(3): Macro Called From
  Module1.asm(428): Include File

; The fld instruction in the macros cannot load immediate values.
; One easy way to deal with this would be to create variables
; that contain the necessary values and pass these to the macros:

zero    REAL10 0.0
one     REAL10 1.0
negone  REAL10 -1.0
...
 
Module1.asm(256) : error A2115: invalid coprocessor register

; The fpu registers must be specified as constants (and there is no st(8)).
; One easy way to deal with this is:

ffree st(0)
ffree st(1)
ffree st(2)
ffree st(3)
ffree st(4)
ffree st(5)
ffree st(6)
ffree st(7)

Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 05, 2008, 04:42:47 AM
QuoteCan you use for example do this?
No.

QuoteCan you do this?
No.


Looks like MichaelW answered the rest of your questions.

Come on etow, you have been given everything you need to write this program. You need to go back and read the tutorials and documentation, you're still missing the basics.

Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 05, 2008, 01:05:14 PM
          To be simple, define A_Number, B_Number and C_Number and the solutions
          RootX0 and RootX1 in data segment.
          So printFormat and calculateQuadraticRoots dont have input parameters.
          They assume the values in that global variables.
          calculateQuadraticRoots put the roots in RootX0 and RootX1 for whatever
          you need.
          In this way you use instructions like  *** fld    A_Number ***
          *** fld    B_Number *** and *** fld    C_Number ***.
         
          Your InputR10 should get the user's integer values and converte it
          to Real10 format A_Number, B_Number and C_Number. Or convert it
          to integers NumberA, NumberB and NumberC and then to reals.

          Test A_Number against 0.0 before calling calculateQuadraticRoot
         
          If A_Number is 0, the equation is first degree or ... It is not
          an Error, Division by zero.

          What do you mean with *** A_Number:Ptr Real10 ***. It means the same
          as A_Number:DWORD if it is a pointer. All pointers here are 32 bits
         

.data
;
; All numbers are real numbers
; ----------------------------
A_Number        REAL10   1.0          ; Put here the Number a
B_Number        REAL10  -1.0          ; Put here the Number b
C_Number        REAL10 -12.0          ; Put here the Number c
;..........................
RootX0          REAL10 ?
RootX1          REAL10 ?
;......................................................................
.code


       
RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 05, 2008, 04:35:11 PM
hi

I found the FPU Tutorial.  I read it and understand it.

Is there a function or procedure to read floating point numbers already in masm32 version 9 library?

Please reply.

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 05, 2008, 04:53:29 PM
Greg's application to me is very complex and confusing to me.
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 05, 2008, 06:42:36 PM
Quote from: etow on February 05, 2008, 04:35:11 PM

Is there a function or procedure to read floating point numbers already in masm32 version 9 library?


             It is a good question. May be MichaelW ( or Greg, sorry Greg ) can answer. I dont know. I dont use any function or proc from masm (i used FpuFLtoA).
             But what do you mean with *** to read floating point numbers  *** ? A procedure you call and let you input only numbers (ascii codes) and +/- and code the result to the format REAL10 ? I dont know.
I think you should get the numbers as a string and then you should convert the string to the number. You should consider that we can type numbers like this: "-123 +45 -87" ! worst: " 123LLKK 1+2"

EDIT:

InputABC        proto :DWORD
.data
StringNumber    db 15 dup (0)           ; space, signal, 12 digits, last 0

.code
InputABC        proc  pABC:DWORD        ; this is a pointer to A_Number, etc.

@@:             ; 1 - Get the alphanumeric string to StringNumber
                ;     This string must be null terminated
               
                ; 2 - Convert StringNumber to REAL10 format
                ;     can use *** FpuAtoFL, lpSrc, lpDest, uID ***
                ;     If EAX=0 go backward to 1 or exit with error
               
                ret
InputABC        endp

          In this way, you use *** invoke InputABC, offset A_Number ***
          *** invoke InputABC, offset B_Number *** ...

RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 05, 2008, 06:47:03 PM
Quote from: etowIs there a function or procedure to read floating point numbers already in masm32 version 9 library?

There is the FpuAtoFL procedure in FPU.LIB.
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 05, 2008, 11:10:16 PM
Hi RuiLoureiro,

What do you mean by:
Get the alphanumeric string to StringNumber
                ;     This string must be null terminated

Do you use mov Number_A, sval(input("Enter a real number for A : )) ?
Or something else?

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 06, 2008, 12:03:05 PM
Quote from: etow on February 05, 2008, 11:10:16 PM
Do you use mov Number_A, sval(input("Enter a real number for A : )) ?
Or something else?

Hi etow,

           I dont know nothing about functions to input values in console applications
           functions like input, crt_sscanf, crt_sprintf, etc. etc. because i dont need to
           use them and i dont want to use them. I dont know where is the documentation, too.
           But you need, you should study them

           I dont like to use macros. I use it only in last cases. I dont know nothing
           about sval, real10$, etc. I dont need, i dont want to use them

           About your question, i think you wrote the procedure Input10 to get the
           alphanumeric string and to convert it to a REAL10 number. You should
           see if it works correctly. I dont Know.
           
Quote
           mov   Number_A, sval(input("Enter a real number for A : ))
           (I dont like to use instructions like this in my programs)
           AFAIK, sval is a macro that converts a string to a 32 bit integer. So,
           Number_A should be an integer.

           One more thing: you can use   ***fild     Mem32 *** where Mem32 is a 32 bit integer
                                   instead of   *** fld     Real10Value ***   

RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 06, 2008, 10:58:46 PM
etow,

The sval macro isn't going to work. What's wrong with InputR10? I wrote it and it works fine for me.

Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 06, 2008, 11:16:27 PM
Hi Greg,

I know that InputR10 works.  After you read in the real numbers, then should I save them to variables so that I could use them for later use in my program?
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 06, 2008, 11:18:56 PM
Hi Greg,

Does your InputR10 reads the floating point or real numbers from the keyboard input from the console as real numbers or ASCII characters?

Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 07, 2008, 12:10:27 AM
etow,

It uses the scanf function from the Microsoft C Run-Time Library. scanf reads ASCII from the standard input and converts it to a REAL8 (the Microsoft C Run-Time Library does not support REAL10 variables) and then converts that to a REAL10.

Alternatively, there is the StdIn procedure in masm32.lib that you could use to input a string and then use FpuAtoFL to convert the string to a REAL10. The functionality would be the same as with InputR10 except that it converts directly to a REAL10.


InputExt PROC pExt:PTR REAL10
    LOCAL szBuffer[64]:BYTE
    INVOKE RtlZeroMemory, ADDR szBuffer, SIZEOF szBuffer
    INVOKE StdIn, ADDR szBuffer, SIZEOF szBuffer
    INVOKE StripLF, ADDR szBuffer
    INVOKE FpuAtoFL, ADDR szBuffer, pExt, DEST_MEM
    ret
InputExt ENDP



Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 07, 2008, 12:20:36 PM
hi Greg and RuiLoureiro

here is my updated code below:
---------------------------------------------------------------------------------------------

.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
NumberA Real10 ?
NumberB Real10 ?
NumberC Real10 ?
Zero  Real10  0.0
NegativeOne Real10 - 1.0
One Real10 1.0
Two DT 2
NegativeFour DT - 4
negativeB Real10 ?
BSquared Real10 ?
temp_real Real10 ?
squareRootNumber Real10 ?
resultOfSquareRoot Real10 ?
negativeResultOfSquareRoot Real10 ?
numerator1 Real10 ?
numerator2 Real10 ?
denominator Real10 ?
xRoot1 Real10 ?
xRoot2 Real10 ?

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================

printQuadraticFormat Proto:Real10, :Real10, :Real10
calculateQuadraticRoots Proto:Real10, :Real10, :Real10

Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(NumberA, Zero) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
     .ElseIf isequal(NumberA, Zero) ; if NumberA == 0.0
    print chr$(13, 10)
    print chr$("Error, Division by Zero!", 13, 10, 13, 10)
     .EndIf
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

       Ffree St(0)
       Ffree St(1)
       Ffree St(2)
       Ffree St(3)
       Ffree St(4)
       Ffree St(5)
       Ffree St(6)
       Ffree St(7)

    .EndW
  Ret
Main EndP

printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

    .If isequal(A_Number, NegativeOne)
    ; if A_Number equals to -1.0
     print chr$("-1.0 X^2 ")
    .ElseIf isequal(A_Number, One)
     ; if A_Number equals to 1.0
       print chr$("1.0 X^2 ")
    .ElseIf (isgreater(A_Number, One) || isless(A_Number, NegativeOne))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       Invoke FpuFLtoA, 0, 4, Addr A_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X^2 ")
    .EndIf

    .If isless(B_Number, NegativeOne)
    ; if B_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .ElseIf isequal(B_Number, NegativeOne)
    ; if B_Number equals to -1.0
       print chr$("-1.0 X ")
    .ElseIf isequal(B_Number, One)
    ; if B_Number equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater(B_Number, One)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .EndIf

    .If isless(C_Number, NegativeOne)
    ; if C_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal(C_Number, NegativeOne)
    ; if C_Number equals to -1.0
       print chr$("-1.0 ")
    .ElseIf isgreater(C_Number, Zero)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .EndIf

Ret
printQuadraticFormat EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

     Invoke FpuMul, Addr B_Number, Addr B_Number, Addr BSquared, SRC1_FPU Or SRC2_REAL Or DEST_FPU
     Invoke FpuMul, Addr NegativeFour, Addr A_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
     Invoke FpuMul, Addr temp_real, Addr C_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
     Invoke FpuAdd, Addr BSquared, Addr temp_real, Addr squareRootNumber, SRC1_REAL Or SRC2_DIMM

    .If isgreaterequal(squareRootNumber, Zero)

      Invoke FpuChs, Addr B_Number, Addr negativeB, SRC1_FPU
      Invoke FpuSqrt, Addr squareRootNumber, Addr resultOfSquareRoot, SRC1_DIMM Or DEST_FPU
      Invoke FpuAdd, Addr negativeB, Addr resultOfSquareRoot, Addr numerator1, SRC1_REAL Or SRC2_DIMM
      Invoke FpuChs, Addr resultOfSquareRoot, Addr negativeResultOfSquareRoot, SRC1_FPU
      Invoke FpuAdd, Addr negativeB, Addr negativeResultOfSquareRoot, Addr numerator2, SRC1_REAL Or SRC2_DIMM
      Invoke FpuMul, Addr Two, Addr A_Number, Addr denominator, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuDiv, Addr numerator1, Addr denominator, Addr xRoot1, SRC1_DIMM Or SRC2_DIMM
      Invoke FpuDiv, Addr numerator2, Addr denominator, Addr xRoot2, SRC1_DIMM Or SRC2_DIMM

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (xRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (xRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

    .ElseIf islessequal(squareRootNumber, NegativeOne)
      ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number


      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
    .EndIf
  Ret

calculateQuadraticRoots EndP

End start


------------------------------------------------------------------------------------------------

I have some problems with the code related to output results
The results are wrong and every time it show the same numbers again.

for example if I enter 1 for A , 0 for B, and -4 for C
the results are  x1 = 0.999995 and x2 = 0.999998

for example if I enter 1 for A, 0 for B, and -9 for C
the results are  x1 = 0.999995 and x2 = 0.999998

I am not sure what the results are like this?
Also the macros for isgreater, isequal, and etc.. do not work well.
I can not make them work properly.

Please help

Thanks

Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 07, 2008, 08:48:10 PM
QuoteAlso the macros for isgreater, isequal, and etc.. do not work well.

What do you mean they don't work well? They have worked fine for me. You don't have to use them. In fact, if you really want to learn assembly language you would be better off not using them. Macros can simplify writing code but you need to understand how they work, otherwise they're just a crutch. I posted them so you (and others) could see the code and see how they work.

Take a look at the uID parameter for the Fpu* functions. You've got problems there.

Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 07, 2008, 09:16:52 PM
Hi etow,
         Let me say this (kindly),
         
         1. You have done a lot of work. But i think your prog is not well structured yet (IMO);
            But it is better, lighter

         2. Copy all macros to a new file, save it with MyMacros.inc,
            remove them form your prog, and add another include
            include   MyMacros.inc (a name you want);

         3. The error is here (i tested it, it is hard to follow):
Quote         
      Invoke FpuMul, Addr B_Number, Addr B_Number, Addr BSquared, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuMul, Addr NegativeFour, Addr A_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuMul, Addr temp_real, Addr C_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuAdd, Addr BSquared, Addr temp_real, Addr squareRootNumber, SRC1_REAL Or SRC2_DIMM

      Invoke FpuChs, Addr B_Number, Addr negativeB, SRC1_FPU
      Invoke FpuSqrt,Addr squareRootNumber, Addr resultOfSquareRoot, SRC1_DIMM Or DEST_FPU
      Invoke FpuAdd, Addr negativeB, Addr resultOfSquareRoot, Addr numerator1, SRC1_REAL Or SRC2_DIMM
      Invoke FpuChs, Addr resultOfSquareRoot, Addr negativeResultOfSquareRoot, SRC1_FPU
      Invoke FpuAdd, Addr negativeB, Addr negativeResultOfSquareRoot, Addr numerator2, SRC1_REAL Or SRC2_DIMM
      Invoke FpuMul, Addr Two, Addr A_Number, Addr denominator, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuDiv, Addr numerator1, Addr denominator, Addr xRoot1, SRC1_DIMM Or SRC2_DIMM
      Invoke FpuDiv, Addr numerator2, Addr denominator, Addr xRoot2, SRC1_DIMM Or SRC2_DIMM

 
            note: you call each one and you dont test if it returns with error or not.
                  you should control it.
                  This is why i said you should put that code in a separate procedure.

        4. If i am understanding english and math, you want to solve this problem:
           a) You have the equation
                                     a x^2  + b x + c = 0
                                     
           b) where a, b, c are integers                                     

           c) you want to get the real roots: x1=xRoot1 and x2= xRoot2.

           d) you want to show the equation and solutions
           
        5. The obvious is this: we need to input a, b, and c as integers
           So we need 3 integer variables, for instance, NumberA, NumberB, NumberC
           If we have something to test, we test this variables. It is easier.

        6. We decided for one method, it needs real numbers ANumber, BNumber, CNumber.
           Ok, we input integers to NumberA and convert it to ANumber, etc.
           You need to decide if you want to pass parameters or if you want
           to define them as global variables. With global, it is easier.
           We decided to use fpu directly. We dont need the variables ANumber,...
           and we dont need to convert them.

        7. If i have all things mixed, i have a lot of problems to test it.
           If i have a set of procedures, i can test each one, i can replace
           one for another without problems.
                   
Rui           
Title: Re: Quadratic Square Root Code Problem
Post by: Sarel on February 07, 2008, 09:26:53 PM
So I messed up your program. :bg
Have a look and dump all those fpu library things except the string manipulation ones.
The FPU unit is quite tricky but just pay attention to what exactly the help file says of the op-codes. :U


;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
NumberA Real10 ?
NumberB Real10 ?
NumberC Real10 ?
Zero  Real10  0.0
NegativeOne Real10 - 1.0
One Real10 1.0
Two DT 2
NegativeFour DT - 4
negativeB Real10 ?
BSquared Real10 ?
temp_real Real10 ?
squareRootNumber Real10 ?
resultOfSquareRoot Real10 ?
negativeResultOfSquareRoot Real10 ?
numerator1 Real10 ?
numerator2 Real10 ?
denominator Real10 ?
xRoot1 Real10 ?
xRoot2 Real10 ?

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ====================================
;Try this procedure instead of the macro (This is just an idea. it will how ever change you logic flow.)
;If r1 greater than r2 then eax is set to 1 (true) else it is set to 0
;Remember the proto statement and modify the other macro's to procedures.
;isgreater proto r1:Real10, r2:Real10

;isgreater proc r1:Real10, r2:Real10

;    finit
;    fld r2
;    fld r1
;    fcompp
;    fstsw ax
;    fwait      ;I dont know if this is needed.
;    sahf
;    jc r1_less_than_r2
;    mov eax,1
;    jmp @f
;  r1_less_than_r2:
;    xor eax,eax
;  @@:
;   ret
;endp


; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================


printQuadraticFormat Proto:Real10, :Real10, :Real10
calculateQuadraticRoots Proto:Real10, :Real10, :Real10


Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(NumberA, Zero) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
     .ElseIf isequal(NumberA, Zero) ; if NumberA == 0.0
       print chr$(13, 10)
       print chr$("Error, Division by Zero!", 13, 10, 13, 10)
     .EndIf
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

       Ffree St(0)
       Ffree St(1)
       Ffree St(2)
       Ffree St(3)
       Ffree St(4)
       Ffree St(5)
       Ffree St(6)
       Ffree St(7)

    .EndW
  Ret
Main EndP

printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

    .If isequal(A_Number, NegativeOne)
    ; if A_Number equals to -1.0
        print chr$("-1.0 X^2 ")
    .ElseIf isequal(A_Number, One)
     ; if A_Number equals to 1.0
       print chr$("1.0 X^2 ")
    .ElseIf (isgreater(A_Number, One) || isless(A_Number, NegativeOne))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       Invoke FpuFLtoA, 0, 4, Addr A_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X^2 ")
    .EndIf

    .If isless(B_Number, NegativeOne)
    ; if B_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .ElseIf isequal(B_Number, NegativeOne)
    ; if B_Number equals to -1.0
       print chr$("-1.0 X ")
    .ElseIf isequal(B_Number, One)
      ; if B_Number equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater(B_Number, One)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .EndIf

    .If isless(C_Number, NegativeOne)
    ; if C_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal(C_Number, NegativeOne)
    ; if C_Number equals to -1.0
       print chr$("-1.0 ")
    .ElseIf isgreater(C_Number, Zero)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .EndIf

   Ret
printQuadraticFormat EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

  ;Square the value of B and store in BSquared
     finit
     fld B_Number
     fld st
     fmul ;st(0) holds the value B*B
     ;fstp BSquared
  ;Get 4*a*c The four is not a negative four it is ((b^2)-(4*a*c)) BE VERY CAREFULL
     fld1
     fld1
     fadd ;st(0) holds 2.0
     fld st
     fadd ;st(0) holds 4.0
     fld A_Number
     fld C_Number
     fmul
     fmul ;4*a*c is in st(0)       B^2 is in st(1)
  ;You need to subtract st(1) - ST(0)
     fsub ;This gives ((b^2)-(4*a*c)) in st(0)
  ;Compare with zero
     fldz
     fcomp st(1) ;((b^2)-(4*a*c)) again in st(0)
     fstsw ax
     sahf
     jc stZero_Less_Than_stOne ; Basicly the part under the root is greater or equal than zero
     jmp NegativeRootError


    ;.If isgreaterequal(squareRootNumber, Zero)
  stZero_Less_Than_stOne:
     fsqrt
     fld st ; make a coppy
     fld B_Number
     fchs
     fadd st(1),st
     fsubrp st(2),st ;st(0) is ((-b) + (the root)) and (st(1) is (-b) - (the root))
     fld A_Number
     fld1
     fld1
     fadd
     fmul ;st(0) holds 2*a
     fld st
     fdivp st(2),st
     fdivp st(2),st ;st(0) is (((-b) + (the root))/2a) and st(1) is (((-b) - (the root))/2a)
     fstp xRoot1
     fstp xRoot2


      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (xRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (xRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)


      jmp OverAndOut


    ;.ElseIf islessequal(squareRootNumber, NegativeOne)
  NegativeRootError:
        ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number


      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
    ;.EndIf

  OverAndOut:

  Ret

calculateQuadraticRoots EndP

End start
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 08, 2008, 12:12:35 AM
Hi RuiLoureiro,
I have done what you told me to do.
Here is my updated code below:
-----------------------------------------------------------------------------------------------------------


.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include MyMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data

Zero  Real10  0.0         ; used to determine if there are real roots in the
                          ; quadratic formula
NegativeOne Real10 - 1.0  ; used in the comparision macros for print format
                          ; procedure
One Real10 1.0     ; used in comparision macros for print format procedure
NumberA Real10 ?   ; coefficient of X^2 in the quadratic equation
NumberB Real10 ?   ; coefficient of X in the quadratic equation
NumberC Real10 ?   ; constant in the quadratic equation
Two DD 2           ; number to use to get the denominator in the quadratic formula
NegativeFour DD - 4 ; number to use to get a square root number in the
                    ; quadratic formula
negativeB Real10 ? ; negating NumberB
BSquared Real10 ?  ; multiplying NumberB by itself
temp_real Real10 ? ; used as temporary variable to get part of the square root
                   ; number
squareRootNumber Real10 ? ; the square root number of the quadratic formula
resultOfSquareRoot Real10 ? ; the result of taking the square root of the number
                            ; in the quadratic formula
negativeResultOfSquareRoot Real10 ? ; negating the result of the square root answer
numerator1 Real10 ?   ; one numerator result of the quadratic formula
numerator2 Real10 ?   ; another numerator result of the quadratic formula
denominator Real10 ?  ; the denominator in the quadratic formula
xRoot1 Real10 ?    ;  one of the real number roots in the quadratic formula
xRoot2 Real10 ?    ;  second of the real number roots in the quadratic formula

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

printQuadraticFormat Proto:Real10, :Real10, :Real10
calculateQuadraticRoots Proto:Real10, :Real10, :Real10
calculateSquareRootNumber Proto:Real10, :Real10, :Real10
calculateXRoots Proto:Real10, :Real10

Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(NumberA, Zero) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
     .ElseIf isequal(NumberA, Zero) ; if NumberA == 0.0
    print chr$(13, 10)
    print chr$("Error, Division by Zero!", 13, 10, 13, 10)
     .EndIf
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

    .EndW
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10


    .If isequal(A_Number, NegativeOne)
    ; if A_Number equals to -1.0
     print chr$("-1.0 X^2 ")
    .ElseIf isequal(A_Number, One)
     ; if A_Number equals to 1.0
       print chr$("1.0 X^2 ")
    .ElseIf (isgreater(A_Number, One) || isless(A_Number, NegativeOne))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       Invoke FpuFLtoA, 0, 5, Addr A_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X^2 ")
    .EndIf

    .If isless(B_Number, NegativeOne)
    ; if B_Number less than -1.0
       Invoke FpuFLtoA, 0, 5, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .ElseIf isequal(B_Number, NegativeOne)
    ; if B_Number equals to -1.0
       print chr$("-1.0 X ")
    .ElseIf isequal(B_Number, One)
    ; if B_Number equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater(B_Number, One)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 5, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .EndIf

    .If isless(C_Number, NegativeOne)
    ; if C_Number less than -1.0
       Invoke FpuFLtoA, 0, 5, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal(C_Number, NegativeOne)
    ; if C_Number equals to -1.0
       print chr$("-1.0 ")
    .ElseIf isgreater(C_Number, Zero)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 5, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .EndIf

Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateSquareRootNumber procedure will calculate the square root number      <<
;<<  before taking its square root                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateSquareRootNumber Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

     Invoke FpuMul, Addr B_Number, Addr B_Number, Addr BSquared, SRC1_FPU Or SRC2_FPU
     ; BSquared = B_Number * B_Number
     Invoke FpuMul, Addr NegativeFour, Addr A_Number, Addr temp_real, SRC1_FPU Or SRC2_FPU
     ; temp_real = NegativeFour * A_Number
     ; temp_real = -4.0 * A_Number
     Invoke FpuMul, Addr temp_real, Addr C_Number, Addr temp_real, SRC1_FPU Or SRC2_FPU
     ; temp_real = temp_real * C_Number
     ; temp_real = -4.0 * A_Number * C_Number
     Invoke FpuAdd, Addr BSquared, Addr temp_real, Addr squareRootNumber, SRC1_REAL Or SRC2_DIMM
     ; squareRootNumber = BSquared + temp_real
     ; squareRootNumber = B_Number * B_Number + -4.0 * A_Number * C_Number

Ret
calculateSquareRootNumber EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc A_Number:Real10, B_Number:Real10

      Invoke FpuChs, Addr B_Number, Addr negativeB, SRC1_FPU
      ; negativeB = -B_Number
      Invoke FpuSqrt, Addr squareRootNumber, Addr resultOfSquareRoot, SRC1_DIMM Or DEST_FPU
      ; resultOfSquareRoot = Sqrt(squareRootNumber)
      Invoke FpuAdd, Addr negativeB, Addr resultOfSquareRoot, Addr numerator1, SRC1_REAL Or SRC2_DIMM
      ; numerator1 = negativeB + resultOfSquareRoot = -B_Number + Sqrt(squareRootNumber)
      Invoke FpuChs, Addr resultOfSquareRoot, Addr negativeResultOfSquareRoot, SRC1_FPU
      ; negativeResultOfSquareRoot = -resultOfSquareRoot = -Sqrt(squareRootNumber)
      Invoke FpuAdd, Addr negativeB, Addr negativeResultOfSquareRoot, Addr numerator2, SRC1_REAL Or SRC2_DIMM
      ; numerator2 = negativeB + negativeResultOfSquareRoot
      ; numerator2 = -B_Number + -Sqrt(squareRootNumber)
      Invoke FpuMul, Addr Two, Addr A_Number, Addr denominator, SRC1_FPU Or SRC2_FPU
      ; denominator = Two * A_Number
      ; denominator = 2.0 * A_Number
      Invoke FpuDiv, Addr numerator1, Addr denominator, Addr xRoot1, SRC1_DIMM Or SRC2_DIMM
      ; xRoot1 = numerator1 / denominator
      ; xRoot1 = (-B_Number + Sqrt(squareRootNumber)) / (2.0 * A_Number)
      Invoke FpuDiv, Addr numerator2, Addr denominator, Addr xRoot2, SRC1_DIMM Or SRC2_DIMM
      ; xRoot2 = numerator2 / denominator
      ; xRoot2 = (-B_Number + -Sqrt(squareRootNumber)) / (2.0 * A_Number)

Ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

     Invoke calculateSquareRootNumber, A_Number, B_Number, C_Number

    .If isgreaterequal(squareRootNumber, Zero)

      Invoke calculateXRoots, A_Number, B_Number

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (xRoot1)   ; print the real number of one real root
                               ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (xRoot2)  ; print the real number of another real root
                              ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

    .ElseIf isless(squareRootNumber, Zero)
      ; if squareRootNumber less than 0.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
    .EndIf
  Ret

calculateQuadraticRoots EndP

End start


------------------------------------------------------------------------------------------

I am not sure which uIDs are correct for each FPU procedures

The uIDs are confusing to me.

Please help

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 08, 2008, 11:43:18 AM
Hi etow,

Quote
The uIDs are confusing to me.

        1. I had the same problems with uIDs
       
        2. The A_Number, B_Number, C_Number, NumberA, NumberB, NumberC are confusing to me

        3. If you do this:
                            NumberA Real10 ?
                            print   chr$("Enter a real number for A : ")
                            Invoke  InputR10, Addr NumberA
           then
                            why  A_Number, B_Number, C_Number

           then
                            why this
                           
                            printQuadraticFormat Proto:Real10, :Real10, :Real10
                            calculateQuadraticRoots Proto:Real10, :Real10, :Real10
                            calculateSquareRootNumber Proto:Real10, :Real10, :Real10
                            calculateXRoots Proto:Real10, :Real10
                           
           when you can use
                            NumberA, NumberB, NumberC
                            and
                            printQuadraticFormat
                            calculateQuadraticRoots
                            calculateSquareRootNumber
                            calculateXRoots

           I am giving you just some ideas. I know you want write your code and learning
           i think. Am i wrong ?
           
           Where is the error now ?
..............................................
EDIT:
        Have o look at this example i did it quickly (p behind means pointer )

; File: Eq3.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc

    Include         \masm32\fpulib\fpu.inc
    IncludeLib   \masm32\fpulib\fpu.lib

RealRoots       proto :DWORD,:DWORD,:DWORD   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
;
; All numbers are real numbers
; ----------------------------
Number0         REAL10  0.0
Number2         REAL10  2.0
Number4         REAL10  4.0
Minus1          REAL10 -1.0
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  1.0 ;1.0
NumberB         Real10  -2.0    ;0.0
NumberC         Real10  -4.0    ;4.0     ;-9.0
;------------------------------------
_RootX0         REAL10 ?
_RootX1         REAL10 ?
   
.data?
;_hInstance      dd ?
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.code
start:
            ;invoke  GetModuleHandle, 0             
            ;mov     _hInstance, eax            ;return value in eax=handle of program

            call    main
            invoke  ExitProcess, 0   
;...................................................
main        proc

            invoke  RealRoots, addr NumberA, addr NumberB, addr NumberC
            jc      _Emain

            cmp     eax, 2
            je      @F

            print   chr$("Real roots")
           
            print   chr$(13, 10)                           
            print   real10$ (_RootX0)
            print   chr$(13, 10)                       
           
            print   real10$ (_RootX1)
            ;
            print   chr$(13, 10)                       
            inkey
            ret
@@:           
            print chr$(" Complex roots ")                       
            inkey
            ret           
            ;
            ;  error
            ; ----------
_Emain:
            print chr$(" Error ")
            ;                       
            ; Stop and wait for a key
            ; -----------------------
            inkey
            ret
main        endp
; ########################################################
RealRoots       proc    pNumA:DWORD, pNumB:DWORD, pNumC:DWORD
                LOCAL   NumB2     :REAL10
                LOCAL   Num4AC    :REAL10
                LOCAL   NumB2_4AC :REAL10
                LOCAL   RootB2_4AC:REAL10
                LOCAL   Num2A     :REAL10

                LOCAL   SOLX0     :REAL10
                LOCAL   SOLX1     :REAL10               

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if >= 0
                ; ------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ---------------------------- 
                               
                mov     eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                stc
                ret
RealRoots       endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end   start
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Sarel,


;Get 4*a*c The four is not a negative four it is ((b^2)-(4*a*c)) BE VERY CAREFULL
     fld1
     fld1
     fadd ;st(0) holds 2.0
     fld st
     fadd ;st(0) holds 4.0
     fld A_Number
     fld C_Number
     fmul
     fmul     

         It isnt a good way to do this. This does what you want
         
     fld    A_Number
     fld    C_Number
     fmul                   ;  ac
     add    st(0), st(0)    ; 2ac
     add    st(0), st(0)    ; 4ac         


                           
Rui                           
Title: Re: Quadratic Square Root Code Problem
Post by: Sarel on February 08, 2008, 03:58:43 PM
Hi etow

You should look at my posting earlier. I modified your "calculateQuadraticRoots" procedure. Copy the whole listing to the editor, assemble and link it. I think it is working now. There is a nice warning at the place where you made a mathmaticle error.

Have fun. :wink
Title: Re: Quadratic Square Root Code Problem
Post by: Sarel on February 08, 2008, 04:17:27 PM
Hi RuiLoureiro

fld    A_Number
     fld    C_Number
     fmul                   ;  ac
     add    st(0), st(0)    ; 2ac
     add    st(0), st(0)    ; 4ac         

That is much better than the way I did it. I noticed etow declared constants 0 ; -1 ; 1 ; 2 and -4, so I used the constant 1 that is within the FPU.
That -4 triggered my respons because that is not a -4 in the formula. ((B*B)-(4*A*C)) That negative means subtract the second part from the first part. It is easy to see that it does change the sign of the second part but please complete the second part first before applying that minus sign.

Greatings.
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 08, 2008, 05:22:39 PM
hi RuiLoureiro
I used your example program but got no results when I compiled it and ran it
what is wrong for the code below?

----------------------------------------------------------------------------------------------------------------


.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data

Zero  Real10  0.0         ; used to determine if there are real roots in the
                          ; quadratic formula
NegativeOne Real10 - 1.0  ; used in the comparision macros for print format
                          ; procedure
Two Real10 2.0     ; number to use to get the denominator in the quadratic formula
One Real10 1.0     ; used in comparision macros for print format procedure
NumberA Real10 ?   ; coefficient of X^2 in the quadratic equation
NumberB Real10 ?   ; coefficient of X in the quadratic equation
NumberC Real10 ?   ; constant in the quadratic equation

NegativeFour Real10 - 4.0 ; number to use to get a square root number in the
                      ; quadratic formula
_xRoot1 Real10 ?    ;  one of the real number roots in the quadratic formula
_xRoot2 Real10 ?    ;  second of the real number roots in the quadratic formula

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

       Invoke calculateQuadraticRoots
       print chr$(13, 10)

;    print chr$(13, 10)
;    print chr$("Error, Division by Zero!", 13, 10, 13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

    .EndW
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

    .If isequal (NumberA, NegativeOne)
    ; if NumberA equals to -1.0
        print chr$("-1.0 X^2 ")
    .ElseIf isequal (NumberA, One)
     ; if NumberA equals to 1.0
          print chr$("1.0 X^2 ")
    .ElseIf (isgreater (NumberA, One) || isless (NumberA, NegativeOne))
     ; if NumberA greater than 1.0 Or A_Number less than - 1.0
          Invoke FpuFLtoA, 0, 5, Addr NumberA, SRC1_FPU Or SRC2_DIMM
          print chr$(" X^2 ")
    .EndIf

    .If isless (NumberB, NegativeOne)
    ; if NumberB less than -1.0
         Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
         print chr$(" X ")
    .ElseIf isequal (NumberB, NegativeOne)
    ; if NumberB equals to -1.0
         print chr$("-1.0 X ")
    .ElseIf isequal (NumberB, One)
    ; if NumberB equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater (NumberB, One)
    ; if NumberB greater than 1.0
        print chr$("+ ")
        Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
        print chr$(" X ")
    .EndIf

    .If isless (NumberC, NegativeOne)
    ; if NumberC less than -1.0
        Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal (NumberC, NegativeOne)
    ; if NumberC equals to -1.0
        print chr$("-1.0 ")
    .ElseIf isgreater (NumberC, Zero)
    ; if NumberC greater than 0.0
        print chr$("+ ")
        Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
    .EndIf

Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

Local NumB2:Real10
Local Num4AC:Real10
Local NumB2_4AC:Real10
Local RootB2_4AC:Real10
Local Num2A:Real10
Local solutionX1:Real10
Local solutionX2:Real10

    Lea Ebx, NumB2
    Invoke FpuMul, pNumB, pNumB, Ebx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Ecx, Num4AC
    Invoke FpuMul, pNumA, pNumC, Ecx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots
;
    Invoke FpuMul, Ecx, Offset NegativeFour, Ecx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Edx, NumB2_4AC
    Invoke FpuSub, Ebx, Ecx, Edx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

; if NumB2_4AC >= 0
;---------------------
    Invoke FpuComp, Edx, Offset Zero, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots
;
    Test Al, 00000100B
    Jz @F
;
; complex roots: NumB2_4AC < 0
;--------------------------------
    Mov Eax, 2
    Clc
    Ret
;
@@:
    Lea Ebx, RootB2_4AC
    Invoke FpuSqrt, Edx, Ebx, SRC1_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Ecx, solutionX1
    Invoke FpuSub, Ebx, pNumB, Ecx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Edx, solutionX2
    Invoke FpuAdd, Ebx, pNumB, Edx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Ebx, Num2A
    Invoke FpuMul, pNumA, Offset Two, Ebx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    ; solutionX1
    Invoke FpuDiv, Ecx, Ebx, Offset _xRoot1, SRC1_REAL Or SRC1_REAL
    Or Eax, Eax
    Jz _rRealRoots

    ; solutionX2
    Invoke FpuDiv, Edx, Ebx, Edx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Invoke FpuMul, Edx, Offset NegativeOne, Offset _xRoot2, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots
    ;
    Mov Eax, 1
    Clc
    Ret
    ;
    ; Eax = 0 => Error
    ;
_rRealRoots:
    Stc
Ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      ; Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_xRoot1)   ; print the real number of one real root
                               ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (_xRoot2)  ; print the real number of another real root
                              ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)
      Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation ")
      print chr$("but it has complex roots! ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      ; Invoke printQuadraticFormat

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                      ; carriage return line feeds to the screen
_ExitProc:

      Ret

calculateQuadraticRoots EndP

End start
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 08, 2008, 05:35:53 PM
hi RuiLoureiro,

Here is my updated code.  I changed your code a little bit.
The results are all zeros.
What is wrong?

---------------------------------------------------------


.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data

Zero  Real10  0.0         ; used to determine if there are real roots in the
                          ; quadratic formula
NegativeOne Real10 - 1.0  ; used in the comparision macros for print format
                          ; procedure
Two Real10 2.0     ; number to use to get the denominator in the quadratic formula
One Real10 1.0     ; used in comparision macros for print format procedure
NumberA Real10 ?   ; coefficient of X^2 in the quadratic equation
NumberB Real10 ?   ; coefficient of X in the quadratic equation
NumberC Real10 ?   ; constant in the quadratic equation

Four Real10 4.0 ; number to use to get a square root number in the
                      ; quadratic formula
_xRoot1 Real10 ?    ;  one of the real number roots in the quadratic formula
_xRoot2 Real10 ?    ;  second of the real number roots in the quadratic formula

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

       Invoke calculateQuadraticRoots

;    print chr$(13, 10)
;    print chr$("Error, Division by Zero!", 13, 10, 13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

    .EndW
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

    .If isequal (NumberA, NegativeOne)
    ; if NumberA equals to -1.0
        print chr$("-1.0 X^2 ")
    .ElseIf isequal (NumberA, One)
     ; if NumberA equals to 1.0
          print chr$("1.0 X^2 ")
    .ElseIf (isgreater (NumberA, One) || isless (NumberA, NegativeOne))
     ; if NumberA greater than 1.0 Or A_Number less than - 1.0
          Invoke FpuFLtoA, 0, 5, Addr NumberA, SRC1_FPU Or SRC2_DIMM
          print chr$(" X^2 ")
    .EndIf

    .If isless (NumberB, NegativeOne)
    ; if NumberB less than -1.0
         Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
         print chr$(" X ")
    .ElseIf isequal (NumberB, NegativeOne)
    ; if NumberB equals to -1.0
         print chr$("-1.0 X ")
    .ElseIf isequal (NumberB, One)
    ; if NumberB equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater (NumberB, One)
    ; if NumberB greater than 1.0
        print chr$("+ ")
        Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
        print chr$(" X ")
    .EndIf

    .If isless (NumberC, NegativeOne)
    ; if NumberC less than -1.0
        Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal (NumberC, NegativeOne)
    ; if NumberC equals to -1.0
        print chr$("-1.0 ")
    .ElseIf isgreater (NumberC, Zero)
    ; if NumberC greater than 0.0
        print chr$("+ ")
        Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
    .EndIf

Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

Local NumB2:Real10
Local Num4AC:Real10
Local NumB2_4AC:Real10
Local RootB2_4AC:Real10
Local Num2A:Real10
Local solutionX1:Real10
Local solutionX2:Real10

    Lea Ebx, NumB2
    Invoke FpuMul, pNumB, pNumB, Ebx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Ecx, Num4AC
    Invoke FpuMul, pNumA, pNumC, Ecx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots
;
    Invoke FpuMul, Ecx, Offset Four, Ecx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Edx, NumB2_4AC
    Invoke FpuSub, Ebx, Ecx, Edx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

; if NumB2_4AC >= 0
;---------------------
    Invoke FpuComp, Edx, Offset Zero, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots
;
    Test Al, 00000100B
    Jz @F
;
; complex roots: NumB2_4AC < 0
;--------------------------------
    Mov Eax, 2
    Clc
    Ret
;
@@:
    Lea Ebx, RootB2_4AC
    Invoke FpuSqrt, Edx, Ebx, SRC1_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Ecx, solutionX1
    Invoke FpuSub, Ebx, pNumB, Ecx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Edx, solutionX2
    Invoke FpuAdd, Ebx, pNumB, Edx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Lea Ebx, Num2A
    Invoke FpuMul, pNumA, Offset Two, Ebx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    ; solutionX1
    Invoke FpuDiv, Ecx, Ebx, Offset _xRoot1, SRC1_REAL Or SRC1_REAL
    Or Eax, Eax
    Jz _rRealRoots

    ; solutionX2
    Invoke FpuDiv, Edx, Ebx, Edx, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots

    Invoke FpuMul, Edx, Offset NegativeOne, Offset _xRoot2, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz _rRealRoots
    ;
    Mov Eax, 1
    Clc
    Ret
    ;
    ; Eax = 0 => Error
    ;
_rRealRoots:
    Stc
Ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      ; Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_xRoot1)   ; print the real number of one real root
                               ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (_xRoot2)  ; print the real number of another real root
                              ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)
      Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation ", 13, 10)
      print chr$("but it has complex roots! ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      ; Invoke printQuadraticFormat

      ;print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                      ; carriage return line feeds to the screen
_ExitProc:
      print chr$(13, 10, 13, 10)

      Ret

calculateQuadraticRoots EndP

End start
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 08, 2008, 06:14:30 PM
Hi etow,
             See now. It is hard to convert procedures ! Dont use *** NegativeFour *** unless you change
             FpuSub  by FpuAdd. But not only !

; File: Eq6.asm
;................................................
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;Include   Macro.inc                      ; i used this         
Include      ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
Number0         REAL10  0.0
Number2         REAL10  2.0
Number4         REAL10  4.0
Minus1          REAL10 -1.0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  1.0 ;1.0
NumberB         Real10  -2.0    ;0.0
NumberC         Real10  -4.0    ;4.0     ;-9.0
;------------------------------------
_RootX0         REAL10 ?
_RootX1         REAL10 ?
; ##############################################################################################

Zero    Real10  0.0       ; used to determine if there are real roots in the
                          ; quadratic formula
NegativeOne Real10 - 1.0  ; used in the comparision macros for print format
                          ; procedure
Two     Real10 2.0        ; number to use to get the denominator in the quadratic formula
One     Real10 1.0        ; used in comparision macros for print format procedure

;NumberA Real10 ?          ; coefficient of X^2 in the quadratic equation
;NumberB Real10 ?          ; coefficient of X in the quadratic equation
;NumberC Real10 ?          ; constant in the quadratic equation

;NegativeFour Real10 - 4.0 ; number to use to get a square root number in the
                          ; quadratic formula
;_xRoot1 Real10 ?          ; one of the real number roots in the quadratic formula
;_xRoot2 Real10 ?          ; second of the real number roots in the quadratic formula
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey          ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
   
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print  chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print  chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print  chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print  chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

       ;Invoke  calculateQuadraticRoots         ; it is correct
       call     calculateQuadraticRoots         ; but when we have no parameters its the same

       print chr$(13, 10)

;       print chr$(13, 10)
;       print chr$("Error, Division by Zero!", 13, 10, 13, 10)

       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

    .EndW
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

    .If isequal (NumberA, NegativeOne)
    ; if NumberA equals to -1.0
           print chr$("-1.0 X^2 ")
    .ElseIf isequal (NumberA, One)
     ; if NumberA equals to 1.0
          print chr$("1.0 X^2 ")
    .ElseIf (isgreater (NumberA, One) || isless (NumberA, NegativeOne))
     ; if NumberA greater than 1.0 Or A_Number less than - 1.0
          Invoke FpuFLtoA, 0, 5, Addr NumberA, SRC1_FPU Or SRC2_DIMM
          print chr$(" X^2 ")
    .EndIf

    .If isless (NumberB, NegativeOne)
    ; if NumberB less than -1.0
         Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
         print chr$(" X ")
    .ElseIf isequal (NumberB, NegativeOne)
    ; if NumberB equals to -1.0
         print chr$("-1.0 X ")
    .ElseIf isequal (NumberB, One)
      ; if NumberB equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater (NumberB, One)
    ; if NumberB greater than 1.0
        print chr$("+ ")
        Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
        print chr$(" X ")
    .EndIf

    .If isless (NumberC, NegativeOne)
    ; if NumberC less than -1.0
        Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal (NumberC, NegativeOne)
    ; if NumberC equals to -1.0
        print chr$("-1.0 ")
    .ElseIf isgreater (NumberC, Zero)
    ; if NumberC greater than 0.0
        print chr$("+ ")
        Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
    .EndIf

   Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                LOCAL   NumB2     :REAL10
                LOCAL   Num4AC    :REAL10
                LOCAL   NumB2_4AC :REAL10
                LOCAL   RootB2_4AC:REAL10
                LOCAL   Num2A     :REAL10

                LOCAL   SOLX0     :REAL10
                LOCAL   SOLX1     :REAL10               

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if >= 0
                ; ------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ---------------------------- 
                               
                mov     eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                stc
                ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; print the real number of another real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)
      Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation ")
      print chr$("but it has complex roots! ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                      ; carriage return line feeds to the screen
_ExitProc:

      ;inkey                                          ; ########### WAS USED TO TEST
      Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start

Rui

Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 08, 2008, 06:29:33 PM
etow,

    If you want to replace names, make a copy of your program (save ti like eq2.asm, eq3.asm, etc.)
use the editor replace text and then test the new. If it is correct, go on. If not go back. Save it next number and repeat. Its a safe way. Sometimes there are problems with replace function: it replaces what we dont want !

Sarel,
        Yes, etow has a problem with -4.
Rui

Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 10, 2008, 02:16:46 AM
Hi RuiLoureiro,

Here is my updated code below:


;................................................
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          REAL10 -1.0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey          ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
   
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print  chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print  chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print  chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print  chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or Eax, Eax
       Jz linear
       Call calculateQuadraticRoots   ; no parameters its the same
                                      ; invoke calculateQuadraticRoots

       print chr$(13, 10)
       Jmp ToContinue

linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or Eax, Eax
       Jz ZeroErrors
       Invoke calculateLinearRoot, Addr NumberB, Addr NumberC
       print chr$(13, 10)
       print chr$(" Solution to linear equation : ")
       print chr$(" ")
       print real10$ (NumberB)
       print chr$(" X ")
       print real10$ (NumberC)
       print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$("X = ")
       print real10$ (_LinearRootX)
       Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10)

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

    .EndW
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

    print chr$(" ")
    print real10$ (NumberA)
    print chr$(" X^2 + ")
    print real10$ (NumberB)
    print chr$(" X + ")
    print real10$ (NumberC)
    print chr$(" = 0 ", 13, 10)

   Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  when NumberA is equal to 0 and NumberB is not equal to 0 and NumberC is not   <<
;<<  equal to 0                                                                    <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc pNumB:DWord, pNumC:DWord
; Bx + C = 0  or  Bx - C = 0

     Local negativeNumC:Real10

     Lea Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL Or SRC2_REAL

     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL

_rLinearRoot:

Ret
calculateLinearRoot EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumA
                ; pNumB is a pointer to NumB
                ; pNumC is a pointer to NumC

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if NumB2_4AC >= 0
                ; ----------------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ----------------------------
                Mov Eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                stc
                ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ", 13, 10)

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; print the real number of another real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)
      Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ", 13, 10)

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat

      print chr$(13, 10, "This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; ! will be outputted along with two
                                      ; carriage return line feeds to the screen
_ExitProc:

      Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start


------------------------------------------------------------------------

I tried getting the solution to Linear equation to work but I could not in the above code.
I need help.  Also, is there a way to get rid of the excess zeros after the decimal point in the answer to the real root solutions of the quadratic equation using the quadratic formula.

What does "lea" mean?  What does  "or eax, eax" do?  What does "jz" mean?  What does "mov eax, 2  and clc " do together?  What does "mov eax, 1 and clc" instructions do together? What does "stc" do?  What does "je @F" do?

I am trying to learn your code so that I know how to use it.

Please reply back soon.

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 10, 2008, 02:33:48 AM
Hi RuiLoureiro,

I also have some more questions.

What does " jz   _rRealRoots" mean?  I know that it is a jump to _rRealRoots       
What does "Jc _ExitProc " mean?
What does "Cmp Eax, 2" do?
                                 
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 10, 2008, 12:21:29 PM
Hi etow,
        1. About «lea»
           Whenever we define a LOCAL variable (inside a procedure)
           like  *** Local NumB2:Real10  ***, to get the initial address of that variable
           in a register,for instance, EBX, we use «lea   ebx, NumB2». Now, the address
           of NumB2 is in EBX. It means also that, now, EBX is the pointer of NumB2. Yes ?

           With global variables (defined in .DATA section ) like *** _RootX0 ***, we get
           a pointer in this way: «mov     ebx, offset _RootX0» ( pointer means address ).

        2. «What does  "or eax, eax" do?  What does "jz" mean?»
            Whenever we return from functions FpuDiv, FpuAdd, FpuSub, etc. etc. the value
            in EAX can be 0 or 1. If it is 0 it means an error occurred. One way to see
            if EAX=0 is «or   eax, eax» - it activates the zero flag -and then Jump if Zero
            «jz». You can do this with cmp  eax, 0, then jz .... It is the same.

        3.  There are 3 ways of exit from *** calculateXRoots Proc ***:
            a) with error the exit is EAX=0 and carry flag set (stc);
            b) roots are real: EAX=1 and carry flag is cleared (clc);
            c) roots are complex: EAX=2 and carry flag  is cleared (clc).
            Then, after you call calculateXRoots, if it comes with carry set
            you can use «jc - jump on carry» to an address process the error case.
            If not, you can test EAX=1 or EAX=2. But you can comment «clc» and «stc»
            inside calculateXRoots and after calculateXRoots, you test EAX=0, EAX=1
            EAX=2 (cmp  eax, 0; cmp, eax, 1; cmp eax, 2).
           
        4. What does "stc" do?
           In the register of flags there is a flag called CARRY. It can be 0 or 1
           0 means cleared and 1 means set. We have 2 instructions to clear and to set
           that flag: clc and stc. You can use it whenever you want.
           To jump if carry is set, use «jc»; to jump if carry is cleared, use «jnc»;

        5.

        or      eax, eax            ; activate the ZERO FLAG, doesnt change eax
        jz      _rRealRoots                                         
           
            The same as
           
        cmp      eax, 0             ; compare eax with 0
        je      _rRealRoots                                                         
           

        Did you solve the Linear equation ?
;..............................................
EDIT:
; replace this

       Invoke InputR10, Addr NumberC

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      linear


; by this

       Invoke InputR10, Addr NumberC

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      ErrorInComp
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       linear                  ; NumberA = 0
      ;
      ; CONTINUE
       ...
;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print   chr$(" Error comparing Number A against zero! ", 13, 10)
        jmp     ToContinue       

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10)


and
;..........................................
linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or     Eax, Eax
       Jz     ZeroErrors
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       ZeroErrors              ; NumberB = 0
       
       Invoke calculateLinearRoot, Addr NumberB, Addr NumberC
       ; etc, etc....
;.........................................................................................
        Inside calculateQuadraticRoots Proc:

      print chr$(13, 10)
      Ret                       ; exit here
      ;Jmp _ExitProc

      print chr$(13, 10, 13, 10) ; ! will be outputted along with two
                                      ; carriage return line feeds to the screen
      Ret                       ; exit here                                     

;......................................................
_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
                        Ret


RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: asmfan on February 10, 2008, 05:12:51 PM
sse (sse2) - sqrtss, sqrtsd, but before chesk sign bit or just make positive by masking this bit.
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 10, 2008, 08:26:46 PM
hi RuiLoureiro,

I have the updated code but the program does nothing.   I am sure the linear equation will not work.  I need help.  Please check my code below.
Thanks.


;................................................
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          REAL10 -1.0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey          ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
   
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print  chr$("quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print  chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print  chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print  chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

       Invoke InputR10, Addr NumberC

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      ErrorInComp
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       Shr Al, 1                   ; mov bit 0 to Carry Flag
       jc       linear                  ; NumberA = 0
       Jmp quadratic

;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print   chr$(" Error comparing Number A against zero! ", 13, 10)
        Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10)
        Jmp ToContinue

linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or     Eax, Eax
       Jz     ZeroErrors
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       ZeroErrors              ; NumberB = 0
       
       Invoke calculateLinearRoot, Addr NumberB, Addr NumberC

       print chr$(" Solution to linear equation : ")
       print chr$(" ----------------------------- ", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)
       print chr$(" X ")
       print real10$ (NumberC)
       print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$("X = ")
       print real10$ (_LinearRootX)
       Jmp ToContinue

;.........................................................................................
quadratic:

      Call calculateQuadraticRoots

      print chr$(13, 10)

      print chr$(13, 10, 13, 10) ; output two carriage return line feeds to
                                 ; the screen
;......................................................

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

    .EndW

_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

    print chr$(" ")
    print real10$ (NumberA)
    print chr$(" X^2 + ")
    print real10$ (NumberB)
    print chr$(" X + ")
    print real10$ (NumberC)
    print chr$(" = 0 ", 13, 10)

   Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  when NumberA is equal to 0 and NumberB is not equal to 0 and NumberC is not   <<
;<<  equal to 0                                                                    <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc pNumB:DWord, pNumC:DWord
; Bx + C = 0  or  Bx - C = 0

     Local negativeNumC:Real10

     Lea Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL Or SRC2_REAL

     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL

Ret
calculateLinearRoot EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumberA
                ; pNumB is a pointer to NumberB
                ; pNumC is a pointer to NumberC

                ; Ax^2 + Bx + C = 0

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if NumB2_4AC >= 0
                ; ----------------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ----------------------------
                Mov Eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                stc
                ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ", 13, 10)
      print chr$(" ---------------------------------- ", 13, 10)

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; print the real number of another real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)
      Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$(" -------------------------------------------------------- ", 13, 10)

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; ! will be outputted along with two
                                      ; carriage return line feeds to the screen
_ExitProc:

      Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 10, 2008, 08:35:22 PM
See the file etow11.zip below. Download it .

BUT:
Include   ComparisonMacros.inc
;include     Macro.inc                              <----------- REMOVE THIS
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord,:DWord
InputR10               Proto :DWORD               ;Ptr Real10
;**************************************************
I am sure the linear equation will work. But it is:


;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  B x + C = 0  =>  x = - C / B
;<<  when NumberA is equal to 0 and NumberB is not equal to 0                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proc  pNumB:DWord, pNumC:DWord
                    Local negativeNumC:Real10
     Lea    Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL                               ;Or SRC2_REAL
     cmp    eax, 0
     je     _rLinearRoot
     ;
     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
                    ; EAX= 0 -> error
_rLinearRoot:
               Ret
calculateLinearRoot EndP


RuiLoureiro

[attachment deleted by admin]
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 10, 2008, 09:40:52 PM
hi RuiLoureiro,

I got it to work except to print the format of the quadratic equation I am having trouble with.
Look at  PrintQuadraticFormat procedure.
I wanted to not print the 0.000000 X if NumberB is 0.0 .  I am not sure how to do this.


;................................................
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          Real10 - 1.0   ; use for negation
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey          ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
   
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$(" Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print  chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print  chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print  chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      ErrorInComp
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       Shr Al, 1                   ; mov bit 0 to Carry Flag
       Jc linear                   ; NumberA = 0
       Jmp quadratic

;.........................................
ErrorInComp:
        print chr$(13, 10)
        print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
        Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10, 13, 10)
        Jmp ToContinue

linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or     Eax, Eax
       Jz     ZeroErrors
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       ZeroErrors              ; NumberB = 0
       
       Invoke calculateLinearRoot, Addr NumberB, Addr NumberC

       print chr$(13, 10, 13, 10)
       print chr$(" Linear Equation: Bx + C ", 13, 10, 13, 10)
       print chr$(" Solution for linear equation : ", 13, 10)
       print chr$(" ----------------------------- ", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)
       print chr$(" X + ")
       print real10$ (NumberC)
       print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$(" X = ")
       print real10$ (_LinearRootX)
       print chr$(13, 10, 13, 10, 13, 10)
       Jmp ToContinue

;.........................................................................................
quadratic:

      Call calculateQuadraticRoots

      print chr$(13, 10) ; output two carriage return line feeds to
                         ; the screen
;......................................................

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
       Invoke ClearScreen
    .EndW

  print chr$(13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

    print chr$(" ")
    print real10$ (NumberA)
    print chr$(" X^2 + ")
    Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
    Or Eax, Eax
    Jz @F
    Jmp XCoefficient

@@:
   print real10$ (NumberC)
   print chr$(" = 0 ", 13, 10)
   Jmp _printExit

XCoefficient:
    print real10$ (NumberB)
    print chr$(" X + ")
    print real10$ (NumberC)
    print chr$(" = 0 ", 13, 10)

_printExit:
   Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  when NumberA is equal to 0 and NumberB is not equal to 0 and NumberC is not   <<
;<<  equal to 0                                                                    <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc pNumB:DWord, pNumC:DWord
; Bx + C = 0  or  Bx - C = 0

     Local negativeNumC:Real10

     Lea Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL Or SRC2_REAL

     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL

Ret
calculateLinearRoot EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumberA
                ; pNumB is a pointer to NumberB
                ; pNumC is a pointer to NumberC

                ; Ax^2 + Bx + C = 0

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if NumB2_4AC >= 0
                ; ----------------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ----------------------------
                Mov Eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:
                Stc
                ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$("   Solutions for quadratic equation : ", 13, 10)
      print chr$(" -------------------------------------- ", 13, 10)

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10, 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; print the real number of another real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)
      Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$(" -------------------------------------------------------- ", 13, 10)

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be outputted
                                 ; to the screen
_ExitProc:

      Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 10, 2008, 09:53:34 PM
etow,

The real10$ macro uses that format by default ("%lf"). Copy the real10$ macro into your program and modify the format string. Look up sprintf for details on the format string.

Or use this macro instead and specify the decimals parameter. ext$(val, 0, 3)
The digits and decimals parameters are optional.


ext$ MACRO r10value:REQ, digits:=<0>, decimals:=<6>
    LOCAL buffer, fmt
    .DATA?
        fmt    DWORD ?
        buffer BYTE  40 DUP(?)
    .CODE
        IFE issize(r10value, 10)
            ECHO -------------------------
            ECHO ext$ - requires REAL10
            ECHO -------------------------
            .ERR
        ENDIF       
        xor eax, eax
        mov al, decimals
        mov ah, digits
        mov fmt, eax
        INVOKE FpuFLtoA, ADDR r10value, fmt, ADDR buffer, (SRC1_REAL OR STR_REG)
        EXITM <OFFSET buffer>
ENDM

Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 10, 2008, 09:54:35 PM
Hi etow,
But Your code is not what i gave you in etow11.zip.

The problem is this, AFAIK: print real10$ (NumberC), prints with 6 decimal places.
To solve your problem, test NumberB. If it is 0.0, print one variable with 0 or one string with 0

edit: See what Greg said

Greg,
         He has the same problem if he uses  *** print ext$(NumberB, 0, 3) *** if NumberB = 0.0.
         He wants to print 0.0 IF NumberB=0.0. So, he should test NumberB.
           
RuiLoureiro

Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 10, 2008, 10:34:26 PM
RuiLoureiro,

OK, I thought he wanted to control the format of the printed number.

Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 10, 2008, 10:36:45 PM
Hi RuiLoureiro,
I got your etow11.zip file and compiled and it works.

Greg and RuiLoureiro, I know you use a macro you mentioned and test for NumberB.

I do not want to print 0.000000 if NumberB and/or NumberC is 0.
For example, if my equation is 1.000000 x^2 + 0.000000 x + 0.000000 = 0
For the 0 coefficient of x and constant 0.  I don't want to print these zeros.
The macro only prints a floating point up to a certain decimal precision.
Am I wrong with this answer?
Title: Re: Quadratic Square Root Code Problem
Post by: GregL on February 10, 2008, 10:49:32 PM
etow,

Try it out for yourself.

Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 11, 2008, 11:34:56 AM
Hi etow,
            Copy the macro ext$ that Greg gave you before to the file ComparisonMacros.inc
             I think printQuadraticFormat does what you want. If you want test Inpu1.zip

printQuadraticFormat Proc

                     print chr$(" ")
                     print ext$(NumberA, 0, 5)
                     print chr$(" X^2 + ")
                     ;
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
                     shr      al, 1                   ; mov bit 0 to Carry Flag
                     jc       NumberBIs0              ; NumberB = 0
   
                     print ext$(NumberB, 0, 5)                     
                     jmp      NextC
                     ;
NumberBIs0:          print ext$(NumberB, 0, 1)
NextC:               print chr$(" X + ")
                     ;
       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL

                     shr      al, 1                   ; mov bit 0 to Carry Flag
                     jc       NumberCIs0              ; NumberC = 0

                     print     ext$(NumberC, 0, 5)
                     jmp       EndPrint
                     ;print chr$(" = 0 ", 13, 10)
                     ;Ret
                     ;
NumberCIs0:          print      ext$(NumberC, 0, 1)
EndPrint:            print      chr$(" = 0 ", 13, 10)
                     Ret
printQuadraticFormat EndP
RuiLoureiro

[attachment deleted by admin]
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 11, 2008, 11:58:17 PM
Hi RuiLoureiro,

I am confused with the code in Input1.zip but I understand the function of it but how do I integrate it into my current code for the printQuadraticFormat?

Here is my updated code below:


;................................................
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord,:DWord
InputR10            Proto :DWORD            ;Ptr Real10

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          REAL10 -1.0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey          ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:DWORD        ;Ptr Real10 the pointer to Real10 value is a DWORD value
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
   
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print  chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print  chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print  chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print  chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      ErrorInComp
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       linear                  ; NumberA = 0
       ;
       Call    calculateQuadraticRoots   ; no parameters its the same
                                         ; invoke calculateQuadraticRoots

       print   chr$(13, 10)
       Jmp     ToContinue
;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
        jmp     ToContinue       
;..........................................
linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or     Eax, Eax
       Jz     ZeroErrors
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       ZeroErrors              ; NumberB = 0
       
        Invoke   calculateLinearRoot, Addr NumberB, Addr NumberC
        cmp      eax, 0
        jne      @F
        ;
        print   chr$(13, 10)
        print   chr$(" Error calculating linear roots", 13, 10)
        jmp     ToContinue

       ;
@@:    print chr$(13, 10)
       print chr$("Linear Equation : Bx + C ", 13, 10)
       print chr$(13, 10)
       print chr$(" Solution for linear equation : ", 13, 10)
       print chr$("-------------------------------", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)

       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
       Shr Al, 1                  ; mov bit 0 to Carry Flag
       Jc NumberCIs0              ; NumberC = 0

       print chr$(" X + ")
       print ext$ (NumberC, 0, 5)
       Jmp Next

NumberCIs0:
   print chr$(" X ")
Next:
   print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$(" X = ")
       print real10$ (_LinearRootX)
       print chr$(13, 10, 13, 10)
       print chr$(13, 10)
       Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10, 13, 10)

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
       Invoke ClearScreen
    .EndW

  print chr$(13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

                     print chr$(" ")
                     print ext$(NumberA, 0, 5)
                     print chr$(" X^2 ")
                     ;
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
                     shr      al, 1                   ; mov bit 0 to Carry Flag
                     Jc NumberBIs0                    ; NumberB = 0

                     print chr$(" + ")
                     print ext$ (NumberB, 0, 5)
                     print chr$(" X ")
                     Jmp NextC
                     ;
NumberBIs0:
NextC:
                     ;
       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
                     Shr Al, 1                   ; mov bit 0 to Carry Flag
                     Jc NumberCIs0              ; NumberC = 0
                     print chr$(" + ")
                     print ext$ (NumberC, 0, 5)
                     jmp       EndPrint

NumberCIs0:
EndPrint:            print chr$(" = 0 ", 13, 10)
                     Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  B x + C = 0  =>  x = - C / B
;<<  when NumberA is equal to 0 and NumberB is not equal to 0                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc  pNumB:DWord, pNumC:DWord
                    Local negativeNumC:Real10

     Lea    Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL                               ;Or SRC2_REAL
     cmp    eax, 0
     je     _rLinearRoot
     ;
     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
                    ; EAX= 0 -> error
_rLinearRoot:
Ret
calculateLinearRoot EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumA
                ; pNumB is a pointer to NumB
                ; pNumC is a pointer to NumC

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if NumB2_4AC >= 0
                ; ----------------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ----------------------------
                Mov Eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                stc
                ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$("  Solutions for quadratic equation : ", 13, 10)
      print chr$("--------------------------------------", 13, 10)

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10, 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; print the real number of another real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

      Ret                       ; exit here
      ;Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$("---------------------------------------------------------", 13, 10)

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; two carriage return line feeds to the screen
      Ret                        ; exit here
;......................................................
_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
    Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
; ##############################################################################################



Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 12, 2008, 12:39:33 PM
Hi etow,         
         Its quite easy if you understood Input1.
         
         1. You want to replace InputR10 by InputABC and you need
             OutputABC in printQuadraticFormat.
            So remove InputR10 and copy InputABC proc and OutputABC  proc
            and paste into your prog (for instance between
            ***calculateQuadraticRoots EndP*** and   ***End     start ***)

         2. ;InputR10    Proto :DWORD                  ; remove this                 
            InputABC     Proto :DWORD,:DWORD,:DWORD    ; add this 

         3. and add this into .DATA

_captionA       db "Input a", 0
_captionB       db "Input b", 0
_captionC       db "Input c", 0
_StringA        db 60 dup (?)
_StringB        db 60 dup (?)
_StringC        db 60 dup (?)
_hInstance      dd ?
_OutBuffer      db 180 dup (?)          ; buffer to handle the equation

        4. After  .start   add this
           ;*****************************
           invoke  GetModuleHandle, 0             
           mov     _hInstance, eax            ;return value in eax=handle of program
           ;*****************************
           because GetTextInput needs _hInstance
           
         5. Remove all ***Invoke InputR10*** and replace by
         ;***************************************************************
            invoke  InputABC, addr NumberA, addr _captionA, addr _StringA
            jc      InputError
            invoke  InputABC, addr NumberB, addr _captionB, addr _StringB
            jc      InputError
            invoke  InputABC, addr NumberC, addr _captionC, addr _StringC
            jc      InputError   
         ;***************************************************************
            and add (you can put it between ErrorInComp: and linear:
IputError:
            print   chr$(13, 10)
            print chr$(" Input Error ", 13, 10, 13, 10)
            jmp     ToContinue                     

         6.  replace printQuadraticFormat by           

printQuadraticFormat      proc
                    call    OutputABC
                    print   offset _OutBuffer
                    print   chr$(13, 10)                                           
                    ret
printQuadraticFormat       endp

         7. Make this correction in InputABC
; Action:
;           Gets the alphanumeric string that stands for a real number
;           Converts that string to a Real10 and put the result into the variable
;           pointed by pABC
         
          I think you can do all this stuff easily. But if you have problems...
          note: if you want to learn how to calculate the roots directly
                  see my post fpuFLtoA problem in Campus.
RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 13, 2008, 01:34:42 AM
Hi RuiLoureiro,

My code updated with your code integrated into it.

Is there any way to change the output more?  The constant +C where C is an integer is two spaces more from the x in for Bx.  Is there a way to decrease the space between Bx and C by one space?

How do I output the format for the Linear Equation like the Quadratic Equation with no extra zeros?


;................................................
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord,:DWord
InputR10            Proto :DWORD            ;Ptr Real10

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          REAL10 -1.0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
_captionA       DB "Input A", 0
_captionB       DB "Input B", 0
_captionC       DB "Input C", 0
_StringA        DB 60 dup (?)
_StringB        DB 60 dup (?)
_StringC        DB 60 dup (?)
_hInstance      DD ?
_OutBuffer      DB 180 dup (?)          ; buffer to handle the equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;*****************************
    Invoke  GetModuleHandle, 0
    Mov _hInstance, Eax            ;return value in eax=handle of program
;*****************************

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey          ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputABC Proto:DWord, :DWord, :DWord

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputABC        proc    pABC:DWORD, pCaption:DWORD, pBuf:DWORD
                LOCAL   Buffer[60]:BYTE
                ;
                push    esi
                push    edi
                ;
                lea     esi, Buffer               
                invoke  GetTextInput, NULL, _hInstance, NULL, pCaption,
                                      NULL, esi
                cmp     eax, 1
                je      _eInputABC                      ; exit                             
                ;
                mov     edi, pBuf                                                             
                xor     ecx, ecx        ; number of digits + 1 sign + 1
                ;
                Xor Edx, Edx
_iInputABC:     movzx   eax, byte ptr [esi + edx]
                inc     edx
                ;
                Cmp Al, 0
                Je _aInputABC
                ;               
                Cmp Al, 20H
                Je _iInputABC              ; space
                ;               
                Cmp Al, 9H
                Je _iInputABC              ; tab
                ;
                Cmp Al, "-"
                Je _nInputABC0
                ;                             
                Cmp Al, "+"
                Je _nInputABC0
                ;
                Cmp Al, "."
                Je _nInputABC0
                ;               
                Cmp Al, "0"
                Jb _eInputABC
                ;
                Cmp Al, "9"
                Ja _eInputABC
                ;
                Mov Byte Ptr [Edi + Ecx], "+"           ; begin with +
                inc     ecx
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_nInputABC0:    mov     byte ptr [edi + ecx], al
                inc     ecx
                ;
_nInputABC:     movzx   eax, byte ptr [esi + edx]
                inc     edx
                ;
                cmp     al, 0
                je      _aInputABC
                ;               
                cmp     al, 20h
                je      _nInputABC
                ;               
                cmp     al, 9h
                je      _nInputABC                               
                ;
                cmp     al, "."
                je     _nInputABC0
                ;                               
                cmp     al, "0"
                jb      _eInputABC
                ;
                cmp     al, "9"
                jbe      _nInputABC0                               
                ja      _eInputABC
                ;     
_aInputABC:     cmp     ecx, 0
                je      _eInputABC                  ; reject
                ;
                cmp     ecx, 12
                ja      _eInputABC                  ; more than 10 digits
                ;
                ; convert
                ; ------- 
                mov     byte ptr [edi + ecx], 0     ; end with 0
                ;
                mov     edx, pABC               
                invoke  FpuAtoFL, edi, edx, DEST_MEM
                or      eax, eax
                jz      _eInputABC                  ; error
                ;
                clc
                pop     edi
                pop     esi
                ret
                ;
_eInputABC:     stc
                pop     edi
                pop     esi
                ret
InputABC EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
OutputABC       proc
                push    edi
                ;
                cld
                mov     edi, offset _OutBuffer
                mov     edx, offset _StringA
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jne     @B
               
@@:             mov     eax, "2^X "
                stosd
                ;
                Mov Al, " "
                stosb
                ;
                mov     edx, offset _StringB
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jne     @B
               
@@:             mov     eax, "  X "
                stosd
                ;
                mov     edx, offset _StringC
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jmp     @B
               
@@:             mov     eax, " 0= "
                stosd
                mov     byte ptr [edi], 0       ; end with 0                             
                ;
                pop     edi
                ret
OutputABC EndP

; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
   
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print  chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       Invoke  InputABC, Addr NumberA, Addr _captionA, Addr _StringA
       Jc InputError
       Invoke  InputABC, Addr NumberB, Addr _captionB, Addr _StringB
       Jc InputError
       Invoke  InputABC, Addr NumberC, Addr _captionC, Addr _StringC
       Jc InputError

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      ErrorInComp
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       linear                  ; NumberA = 0
       ;
       Call    calculateQuadraticRoots   ; no parameters its the same
                                         ; invoke calculateQuadraticRoots

       print   chr$(13, 10)
       Jmp     ToContinue
;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
        jmp     ToContinue       
;..........................................
InputError:
            print   chr$(13, 10)
            print chr$(" Input Error ", 13, 10, 13, 10)
            jmp     ToContinue                     
;..........................................
linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or     Eax, Eax
       Jz     ZeroErrors
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       ZeroErrors              ; NumberB = 0
       
        Invoke   calculateLinearRoot, Addr NumberB, Addr NumberC
        cmp      eax, 0
        jne      @F
        ;
        print   chr$(13, 10)
        print   chr$(" Error calculating linear roots", 13, 10)
        jmp     ToContinue

       ;
@@:    print chr$(13, 10)
       print chr$("linear Equation : Bx + C ", 13, 10)
       print chr$(13, 10)
       print chr$(" Solution for linear equation : ", 13, 10)
       print chr$("-------------------------------", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)

       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
       Shr Al, 1                  ; mov bit 0 to Carry Flag
       Jc NumberCIs0              ; NumberC = 0

       print chr$(" X + ")
       print ext$ (NumberC, 0, 5)
       Jmp Next

NumberCIs0:
   print chr$(" X ")
Next:
   print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$(" X = ")
       print real10$ (_LinearRootX)
       print chr$(13, 10, 13, 10)
       print chr$(13, 10)
       Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10, 13, 10)

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
       Invoke ClearScreen
    .EndW

  print chr$(13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat      proc
                    Call OutputABC
                    print chr$(" ")
                    print   offset _OutBuffer
                    print   chr$(13, 10)                                           
                    ret
printQuadraticFormat       endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  B x + C = 0  =>  x = - C / B
;<<  when NumberA is equal to 0 and NumberB is not equal to 0                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc  pNumB:DWord, pNumC:DWord
                    Local negativeNumC:Real10

     Lea    Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL                               ;Or SRC2_REAL
     cmp    eax, 0
     je     _rLinearRoot
     ;
     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
                    ; EAX= 0 -> error
_rLinearRoot:
Ret
calculateLinearRoot EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumA
                ; pNumB is a pointer to NumB
                ; pNumC is a pointer to NumC

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if NumB2_4AC >= 0
                ; ----------------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ----------------------------
                Mov Eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                stc
                ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

      print chr$(13, 10)
      print chr$("  Solutions for quadratic equation : ", 13, 10)
      print chr$("--------------------------------------", 13, 10)

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10, 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; print the real number of another real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

      Ret                       ; exit here
      ;Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$("---------------------------------------------------------", 13, 10)

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; two carriage return line feeds to the screen
      Ret                        ; exit here
;......................................................
_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
    Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
; ##############################################################################################
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 13, 2008, 03:23:20 PM
Hi etow,         
         Its quite easy if you understood OutputABC. Read it and try to understand how
         it works. Repace printQuadraticFormat name by printEquation and use
         it to print b X + c = 0 also. Define a flag _FlgEqType. When you call
         a quadratic equation, put _FlgEqType=1; when you call a linear equation
         put _FlgEqType=0. Then inside OutputABC, use _FlgEqType to get
         a x^2 + b x + c = 0 or only b x + c = 0 to _OutBuffer.
         Another thing: we dont need to define another variable _LinearRootX.
                        We can use _RootX0. Its more simple
         I think it is better to put InputABC and OutputABC at the bottom, not
         at the top. When we want to follow the program we begin at «start:» and
         we begin to see it first. To end the program it is better to use 1
         instead of -1. We dont need to type 2 things. Return-> continues; 1=Quit.
         You can consider to improve printEquation in such a way that it prints
         the roots also.
         
RuiLoureiro         


[attachment deleted by admin]
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 13, 2008, 05:32:04 PM
Hi RuiLoureiro,
I don't see the printEquation file in the zip file

Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 13, 2008, 05:44:16 PM
Quote from: etow on February 13, 2008, 05:32:04 PM
I don't see the printEquation file in the zip file
here (its not a file but a proc):
       ; ******************
       ;        Exit
       ; ******************
            print    chr$(13, 10)
            inkey           ; pause the screen while waiting for user to press any key
                            ; to continue
            invoke    ExitProcess, 0                   ; exit from program
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printEquation will output the quadratic equation entered by user    <<
;<<   to the screen                                                       <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
printEquation       proc
RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 13, 2008, 11:19:01 PM
Hi RuiLoureiro,

I have some questions for you.

What does the "cld" do?  What does the instructions "stosb" and "stosd" do?
What does "je @F"  jump to ?   What does "jne @B" jump to ?"  What does byte ptr[edi] mean?
What does "movzx eax, byte ptr [edx] "mean?

Thanks
Title: Re: Quadratic Square Root Code Problem
Post by: RuiLoureiro on February 14, 2008, 12:15:09 PM
Quote from: etow on February 13, 2008, 11:19:01 PM
What does the "cld" do?  What does the instructions "stosb" and "stosd" do?
What does "je @F"  jump to ?   What does "jne @B" jump to ?"  What does byte ptr[edi] mean?
What does "movzx eax, byte ptr [edx] "mean?

Hi etow,
             Try to understand this example: You define a variable in .DATA section
             for 30 bytes. For instance:   _ThisVariable      DB 30 dup (?)
             Whats the address of that variable ? Simply offset _ThisVariable. To put
             that address in the register EDI: mov      edi, offset _ThisVariable.
             Now you want to put bytes begining at the address EDI up to 30 bytes.
             
            1. stosb   means store single byte and moves the byte in AL to the address
                       which is in register EDI and, at the end, the register EDI
                       is incremented (if DF is 0) or decremented (if DF is 1).
                       DF means Direction Flag.
                       If you want to go from lower addresses to higher,
                       you must put DF to 0. We do this with the
                       instruction CLD (Clear Direction). If you want to go from higher
                       addresses to lower, you must put DF to 1. We do this with the
                       instruction STD (Set Direction). Generally we use CLD to
                       go from top to bottom

                stosd   stores the value in EAX. At the end EDI=EDI+4 if DF=0 and...

            Now think about this case: mov   edi, offset _ThisVariable
                                       add   edi, 29
            Where are we ? If you want to go to the top, to the address offset _ThisVariable,
            using instructios stosb or stosd, we need to do STD before. Yes ?
                                       
            2. About "@F" and "@B" and labels @@:
               Look at this 2 examples

; this case i use labels _previous and _next
_previous:      mov     al, byte ptr [esi]      ; move the byte at the address ESI to AL
                cmp     al, 0
                je      _next     
                ...
                inc     esi
                jmp     _previous
_next:          ...


; this case i use labels @@ and "@F" and "@B"
@@:             mov     al, byte ptr [esi]  ; move the byte at the address ESI to AL
                cmp     al, 0
                je      @F                  ; label @@ forward
                ...
                inc     esi
                jmp     @B  ; jump to the label @@ backward, defined before this point here
@@:             ...

            3. byte ptr [edi], byte ptr[edx] means the byte which is in the address EDI, EDX
            4. movzx    eax, byte ptr [edx] means move the byte which is in the address EDX
               to AL and complete the register eax with zeros. If the byte at the address
               EDX is 30h, at the end, the four bytes in eax are EAX= 00 00 00 30h
                                                                                                      AH AL
            You need to get a manual. All this stuff is there.
             I hope this help you
RuiLoureiro
Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 15, 2008, 04:09:35 PM
Hi RuiLoureiro,  I understand your explanation and try to modify my code.
I commented where I modify the code to try to shrink the space between the X term and the constant but could not get it to work.

Please give me some hints.
-------------------------------------------------------------------------------------------------


;................................................
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord, :DWord
InputABC Proto:DWord, :DWord, :DWord

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          Real10 - 1.0   ; used for negation
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
_captionA       DB "Input A", 0  ; input windows box for the coefficient of X^2
                                 ; of quadratic equation
_captionB       DB "Input B", 0  ; input windows box for the coefficient of X
                                 ; of quadratic equation
_captionC       DB "Input C", 0  ; input windows box for the constant
                                 ; of quadratic equation
_StringA        DB 60 Dup (?) ; output string for the input for coefficient X^2
                              ; quadratic equation concatenate with X^2
_StringB        DB 60 Dup (?) ; output string for the input for coefficient X
                              ; quadratic equation along concatenate with X
_StringC        DB 60 Dup (?) ; output string for the input for constant
                              ; quadratic equation
_hInstance      DD ?
_OutBuffer      DB 180 Dup (?)  ; buffer to handle the equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;*******************************
    Invoke  GetModuleHandle, 0
    Mov _hInstance, Eax            ;return value in eax=handle of program
;*******************************

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey          ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   InputABC procedure will convert input from keyboard   <<<
;<<   using windows boxes into real10 numbers               <<<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputABC        proc    pABC:DWORD, pCaption:DWORD, pBuf:DWORD
                Local Buffer[64]:Byte
                ;
                push    esi
                push    edi
                ;
                Lea Esi, Buffer  ; Esi is the pointer address of Buffer
                invoke  GetTextInput, NULL, _hInstance, NULL, pCaption,
                                      NULL, esi
                Cmp Eax, 1   ; compare Eax with 1
                je      _eInputABC                      ; exit                             
                ;
                mov     edi, pBuf                                                             
                xor     ecx, ecx        ; number of digits + 1 sign + 1
                ;
                Xor Edx, Edx
_iInputABC:     movzx   eax, byte ptr [esi + edx]
                Inc Edx      ; edx = edx + 1
                ;
                Cmp Al, 0         ; compare Al with 0
                Je _aInputABC
                ;               
                Cmp Al, 20H      ; compare Al with 20H
                Je _iInputABC              ; space
                ;               
                Cmp Al, 9H      ; compare Al with 9H
                Je _iInputABC              ; tab
                ;
                Cmp Al, "-"     ; compare Al with character "-"
                Je _nInputABC0
                ;                             
                Cmp Al, "+"    ; compare Al with character "+"
                Je _nInputABC0
                ;
                Cmp Al, "."    ; compare Al with character "."
                Je _nInputABC0
                ;               
                Cmp Al, "0"    ; compare Al with character "0"
                Jb _eInputABC
                ;
                Cmp Al, "9"    ; compare Al with character "9"
                Ja _eInputABC
                ;
                Mov Byte Ptr [Edi + Ecx], "+"           ; begin with +
                Inc Ecx    ;  ecx = ecx + 1
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_nInputABC0:    mov     byte ptr [edi + ecx], al
                Inc Ecx  ; ecx = ecx + 1
                ;
_nInputABC:     movzx   eax, byte ptr [esi + edx]
                Inc Edx  ; edx = edx + 1
                ;
                Cmp Al, 0   ; compare Al with 0
                je      _aInputABC
                ;               
                Cmp Al, 20H     ; compare Al with 20h
                je      _nInputABC
                ;               
                Cmp Al, 9H  ; compare Al with 9h
                je      _nInputABC                               
                ;
                Cmp Al, "."     ; compare Al with character "."
                je     _nInputABC0
                ;                               
                Cmp Al, "0"     ; compare Al with character "0"
                jb      _eInputABC
                ;
                Cmp Al, "9"  ; compare Al with character "9"
                jbe      _nInputABC0                               
                ja      _eInputABC
                ;     
_aInputABC:     Cmp Ecx, 0 ; compare Ecx with 0
                je      _eInputABC                  ; reject
                ;
                Cmp Ecx, 12  ; compare Ecx with 12
                ja      _eInputABC                  ; more than 10 digits
                ;
                ; convert
                ; ------- 
                mov     byte ptr [edi + ecx], 0     ; end with 0
                ;
                mov     edx, pABC               
                invoke  FpuAtoFL, edi, edx, DEST_MEM
                Or Eax, Eax  ; activate zero flag
                jz      _eInputABC                  ; error
                ;
                clc
                pop     edi
                pop     esi
                ret
                ;
_eInputABC:     stc
                pop     edi
                pop     esi
                ret
InputABC EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  OutputABC procedure will output the format of the user's quadratic equation  <<
;<<  without the extra zeros                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

OutputABC       proc
                push    edi
                ;
                cld
                mov     edi, offset _OutBuffer
                mov     edx, offset _StringA
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jne     @B
               
@@:             Mov Eax, "2^X "
                stosd
                ;
                Mov Al, " "
                Stosb
                ;
                mov     edx, offset _StringB
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                Jne @B
               
@@:             Mov Eax, "  X "
                Stosd
                ;
                Cld          ; try to shrink the space between the X term and constant
                Sub Edx, 1   ; try to shrink the space between the X term and constant
                Mov Edx, Offset _StringC
                ;
@@:             Movzx Eax, Byte Ptr [Edx]
                Inc Edx
                cmp     al, 0
                je      @F
                ;
                Stosb
                jmp     @B
               
@@:             Mov Eax, "0 = "
                stosd
                mov     byte ptr [edi], 0       ; end with 0                             
                ;
                pop     edi
                ret
OutputABC EndP

; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
   
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       Invoke  InputABC, Addr NumberA, Addr _captionA, Addr _StringA
       Jc InputError ; jump on carry flag
       Invoke  InputABC, Addr NumberB, Addr _captionB, Addr _StringB
       Jc InputError ; jump on carry flag
       Invoke  InputABC, Addr NumberC, Addr _captionC, Addr _StringC
       Jc InputError ; jump on carry flag

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or Eax, Eax   ; activate zero flag
       Jz ErrorInComp ;  jump equal to zero, if Eax = 0
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       Shr Al, 1        ; mov bit 0 to Carry Flag
       Jc linear        ; jump on carry flag , NumberA = 0
       ;
       Call    calculateQuadraticRoots   ; no parameters its the same
                                         ; invoke calculateQuadraticRoots

       print   chr$(13, 10)
       Jmp     ToContinue
;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
        jmp     ToContinue       
;..........................................
InputError:
            print   chr$(13, 10)
            print chr$(" Input Error ", 13, 10, 13, 10)
            jmp     ToContinue                     
;..........................................
linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or Eax, Eax ; activate zero flag
       Jz ZeroErrors  ; jump equal to zero, if Eax = 0
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       Shr Al, 1         ; mov bit 0 to Carry Flag
       Jc ZeroErrors     ; jump on carry flag ,  NumberB = 0
       
        Invoke   calculateLinearRoot, Addr NumberB, Addr NumberC
        Cmp Eax, 0  ; Compare Eax with 0
        Jne @F  ; jump not equal to 0
        ;
        print   chr$(13, 10)
        print   chr$(" Error calculating linear roots", 13, 10)
        jmp     ToContinue

       ;
@@:    print chr$(13, 10)
       print chr$("linear Equation : Bx + C ", 13, 10)
       print chr$(13, 10)
       print chr$(" Solution for linear equation : ", 13, 10)
       print chr$("-------------------------------", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)

       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
       Shr Al, 1          ; mov bit 0 to Carry Flag
       Jc NumberCIs0      ; jump on carry flag  ,  NumberC = 0

       print chr$(" X + ")
       print ext$ (NumberC, 0, 5)
       Jmp Next

NumberCIs0:
   print chr$(" X ")
Next:
   print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$(" X = ")
       print real10$ (_LinearRootX)
       print chr$(13, 10, 13, 10)
       print chr$(13, 10)
       Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10, 13, 10)

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
       Invoke ClearScreen
    .EndW

  print chr$(13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat      proc
                    Call OutputABC
                    print chr$(" ")
                    print   offset _OutBuffer
                    print   chr$(13, 10)                                           
                    ret
printQuadraticFormat       endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  B x + C = 0  =>  x = - C / B
;<<  when NumberA is equal to 0 and NumberB is not equal to 0                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc  pNumB:DWord, pNumC:DWord
                    Local negativeNumC:Real10

     Lea Edx, negativeNumC ; Edx is the pointer address of negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL
     Cmp Eax, 0 ; compare Eax with 0 , activate the zero flag
     Je _rLinearRoot ; jump equal to 0
     ;
     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
                    ; EAX= 0 -> error
_rLinearRoot:
Ret
calculateLinearRoot EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumA
                ; pNumB is a pointer to NumB
                ; pNumC is a pointer to NumC

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                Lea Ebx, NumB2 ; Ebx is the pointer address of NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots    ; jump on zero,  Eax = 0   , error -> exit
               
                Lea Ecx, Num4AC ; Ecx is the pointer address of Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots   ; jump on zero,  Eax = 0   , error -> exit
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots    ; jump on zero,  Eax = 0   , error -> exit

                Lea Edx, NumB2_4AC ; Edx is the pointer address of NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                ;
                ; Test if NumB2_4AC >= 0
                ; ----------------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ----------------------------
                Mov Eax, 2 ; -> roots are complex
                Clc        ; -> carry flag is cleared
                ret
                ;
@@:             Lea Ebx, RootB2_4AC  ; Ebx is the pointer address of RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots   ; jump on zero,  Eax = 0   , error -> exit

                Lea Ecx, SOLX0  ; Ecx is the pointer address of SOLXO
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots   ; jump on zero,  Eax = 0   , error -> exit

                Lea Edx, SOLX1 ; Edx is the pointer address of SOLX1
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit

                Lea Ebx, Num2A  ; Ebx is the pointer address of Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                ;
                Mov Eax, 1  ; -> roots are real
                Clc         ; -> carry flag is cleared
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                Stc ; -> set flag
                ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc  ; jump on carry flag

      Cmp Eax, 2  ;  Compare Eax with 2
      Je @F       ;  jump equal to 2

      print chr$(13, 10)
      print chr$("  Solutions for quadratic equation : ", 13, 10)
      print chr$("--------------------------------------", 13, 10)

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10, 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; print the real number of another real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

      Ret                       ; exit here

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$("---------------------------------------------------------", 13, 10)

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; two carriage return line feeds to the screen
      Ret                        ; exit here
;......................................................
_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
    Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
; ##############################################################################################

Title: Re: Quadratic Square Root Code Problem
Post by: etow on February 19, 2008, 04:07:25 PM
Hi

Here is the program in zip file for quadratic formula to solve quadratic equation for real solutions:

[attachment deleted by admin]