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

Jimg

hint:  2147483647 decimal = 7FFFFFFF hex = -1 with the topmost bit removed. 

etow

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? 

etow

How can I convert these long integer values into negative numbers?

Please help

Thanks

askm

You have not worked
with this in a
higher level language ?

etow

well I did not have to worry about this in high level language.


etow

I did not have to display anything negative before

Jimg

#21
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.

RuiLoureiro

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 

etow

Hi RuiLoureiro,
Thanks for your help
I got it to work.


etow

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


etow

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?


GregL

etow,

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

Take a look at Simply FPU. It has everything you ever wanted to know about using the FPU.

Here is a program I posted that makes extensive use of FPU.




RuiLoureiro

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

GregL

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.



RuiLoureiro

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