home *** CD-ROM | disk | FTP | other *** search
- DECLARE SUB CUBERT (C#(), RT#(), FLAG%)
- ' Cubic equation solve routine.
- ' Illustrates usage of subroutine CUBERT
- start:
- CLS 0
- LOCATE 10
- DIM A#(3), X#(3)
-
- INPUT "Enter coefficient of cubic term"; A#(3)
- INPUT "Enter coefficient of quadratic term"; A#(2)
- INPUT "Enter coefficient of linear term"; A#(1)
- INPUT "Enter constant term"; A#(0)
- PRINT "The roots of the equation - "
- CALL CUBERT(A#(), X#(), F%)
- IF F% = 2 THEN ' 1 real and conjugate pair
- X1# = R# - AAS# / 3
- PRINT "x1 = "; X#(1)
- PRINT "x2 = "; X#(2); " + "; X#(3); " i "
- PRINT "x3 = "; X#(2); " - "; X#(3); " i "
- ELSE ' 3 real and distinct roots
- PRINT "x1 = "; X#(1)
- PRINT "x2 = "; X#(2)
- PRINT "x3 = "; X#(3)
- END IF
- P# = A#(3)
- FOR I% = 1 TO 3
- P# = P# * X#(1) + A#(3 - I%)
- NEXT I%
- PRINT
- ' Display value of equation at root as check
- PRINT "Value of equation at root1 =: "; P#
- END
-
- SUB CUBERT (C#(), RT#(), FLAG%) STATIC
-
- ' Double Precision Cubic equation solve routine.
- ' Solves by Cardan's method.
- ' Written by Richard G. Jones 3/7/88
- '
- ' Call with:
- ' C#() = 4 coefficients in elements 0 - 3
- ' RT#() = array with at least 4 elements.
- ' Returns:
- ' FLAG% = status; one of the following:
- '
- ' = 1: 3 real and distinct roots in RT#(1) - RT#(3) (r1 - r3)
- ' = 2: roots are given as follows
- ' x1 = RT#(1)
- ' x2 = RT#(2) + RT#(3) * i
- ' x3 = RT#(2) - RT#(3) * i where i = SquareRoot(-1)
- '
- ' note: Possible root multiplicities in case 2 could occur.
- ' if r3 = 0 and r1 <> r2 there is a double root.
- ' if r3 = 0 and r1 = r2 there is a triple root
-
- CONST PI# = 3.141592653589793#, BIG# = 1D+40
-
- ' assign coef's to locals to eliminate array indexing
-
- A3# = C#(3)
-
- ' calculate coefficients of Cardan's reduced cubic (p & q):
- ' u^3 + p * u + q = 0
-
- AAS# = C#(2) / A3#: BS# = C#(1) / A3#
- CS# = C#(0) / A3#
- P# = BS# - AAS# ^ 2# / 3#
- Q# = 2# * (AAS# / 3#) ^ 3# - BS# * AAS# / 3# + CS#
-
- ' calculate discriminant D.
- ' If D > 0 there are 1 real and a pair of complex conjugate roots.
- ' D = 0 all roots are real and at least 2 are equal.
- ' D < 0 all roots are real and distinct.
-
-
- D# = (P# / 3#) ^ 3# + (Q# / 2#) ^ 2#
- U# = -Q# / 2#
-
- IF D# >= 0# THEN
- ' case of 1 real root and a pair of complex conjugates or multiple roots
-
- A33# = (U# + SQR(D#))
- B33# = (U# - SQR(D#))
- IF A33# < 0# THEN
- A# = -(ABS(A33#) ^ (1# / 3#))
- ELSE
- A# = A33# ^ (1# / 3#)
- END IF
- IF B33# < 0# THEN
- B# = -(ABS(B33#) ^ (1# / 3#))
- ELSE
- B# = B33# ^ (1# / 3#)
- END IF
- R# = A# + B#
- S# = (A# - B#) * 3# ^ .5#
- RT#(1) = R# - AAS# / 3 ' real root
- RT#(2) = -(R# / 2# + AAS# / 3#) ' real component of conjugates
- RT#(3) = ABS(S#) ' imaginary component
- FLAG% = 2
-
- ELSE
- ' case of 3 real and distinct roots.
-
- MAG# = SQR(U# ^ 2# - D#)
- DG# = SQR(-D#)
- IF ABS(DG#) < ABS(U#) * BIG# THEN
- THETA# = ATN(ABS(DG# / U#))
- IF U# < 0 THEN THETA# = PI# - THETA#
- ELSE
- THETA# = PI# / 2#
- END IF
-
- R# = MAG# ^ (1# / 3#) * COS(THETA# / 3#)
- S# = MAG# ^ (1# / 3#) * SIN(THETA# / 3#) * 3# ^ .5#
- C# = AAS# / 3#
- RT#(1) = 2# * R# - C# ' return 3 roots
- RT#(2) = -R# + S# - C#
- RT#(3) = -R# - S# - C#
- FLAG% = 1
-
- END IF
-
- END SUB
-