News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Quadratic Square Root Code Problem

Started by etow, January 30, 2008, 03:13:23 PM

Previous topic - Next topic

Sarel

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.

etow

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

etow

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

RuiLoureiro

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


RuiLoureiro

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


etow

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

etow

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?
                                 

RuiLoureiro

#67
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

asmfan

sse (sse2) - sqrtss, sqrtsd, but before chesk sign bit or just make positive by masking this bit.
Russia is a weird place

etow

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

RuiLoureiro

#70
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]

etow

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

GregL

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


RuiLoureiro

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


GregL

RuiLoureiro,

OK, I thought he wanted to control the format of the printed number.