From 6c98f2c5d7d3c4adcfd0fa522561f52f48a79adc Mon Sep 17 00:00:00 2001 From: Gatecraft Date: Tue, 12 Jul 2016 22:26:54 +0200 Subject: [PATCH] Update --- .classpath | 15 +- .gitignore | 25 +- .settings/org.eclipse.core.resources.prefs | 18 +- out.txt | 88 - src/org/nevec/rjm/Bernoulli.java | 7 +- src/org/nevec/rjm/BigDecimalMath.java | 69 +- src/org/nevec/rjm/BigIntegerMath.java | 8 +- src/org/nevec/rjm/BigIntegerPoly.java | 8 +- src/org/nevec/rjm/BigSurd.java | 24 +- src/org/nevec/rjm/BigSurdVec.java | 55 +- src/org/nevec/rjm/Ifactor.java | 5 +- src/org/nevec/rjm/RatPoly.java | 29 +- src/org/nevec/rjm/Rational.java | 1474 +++++++++-------- src/org/nevec/rjm/Wigner3j.java | 17 +- src/org/nevec/rjm/Wigner3jGUI.java | 12 +- .../warpgate/pi/calculator/Calculator.java | 72 +- src/org/warpgate/pi/calculator/Divisione.java | 190 ++- src/org/warpgate/pi/calculator/Errori.java | 21 +- src/org/warpgate/pi/calculator/Funzione.java | 20 +- .../pi/calculator/FunzioneAnteriore.java | 66 + .../pi/calculator/FunzioneDueValori.java | 120 +- .../pi/calculator/FunzioneMultipla.java | 125 +- .../pi/calculator/FunzioneSingola.java | 20 - src/org/warpgate/pi/calculator/Main.java | 243 ++- .../pi/calculator/Moltiplicazione.java | 100 +- src/org/warpgate/pi/calculator/Parentesi.java | 985 +++++++---- src/org/warpgate/pi/calculator/Potenza.java | 64 +- src/org/warpgate/pi/calculator/Radice.java | 63 +- .../pi/calculator/RadiceQuadrata.java | 66 +- src/org/warpgate/pi/calculator/Simboli.java | 77 +- src/org/warpgate/pi/calculator/Somma.java | 80 +- src/org/warpgate/pi/calculator/Termine.java | 521 ++++-- src/org/warpgate/pi/calculator/Utils.java | 522 ++++-- .../pi/calculator/VariabileEdEsponente.java | 25 - 34 files changed, 3371 insertions(+), 1863 deletions(-) delete mode 100644 out.txt create mode 100644 src/org/warpgate/pi/calculator/FunzioneAnteriore.java delete mode 100644 src/org/warpgate/pi/calculator/FunzioneSingola.java delete mode 100644 src/org/warpgate/pi/calculator/VariabileEdEsponente.java diff --git a/.classpath b/.classpath index fb501163..8c8deeaa 100644 --- a/.classpath +++ b/.classpath @@ -1,6 +1,9 @@ - - - - - - + + + + + + + + + diff --git a/.gitignore b/.gitignore index 32858aad..eae78d9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,13 @@ -*.class - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +/bin/ diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index 4ad139ea..5ea8e9a7 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,8 +1,10 @@ -eclipse.preferences.version=1 -encoding//src/org/nevec/rjm/BigSurd.java=UTF-8 -encoding//src/org/nevec/rjm/BigSurdVec.java=UTF-8 -encoding//src/org/warpgate/pi/calculator/Main.java=UTF-8 -encoding//src/org/warpgate/pi/calculator/Parentesi.java=UTF-8 -encoding//src/org/warpgate/pi/calculator/Radice.java=UTF-8 -encoding//src/org/warpgate/pi/calculator/RadiceQuadrata.java=UTF-8 -encoding//src/org/warpgate/pi/calculator/Simboli.java=UTF-8 +eclipse.preferences.version=1 +encoding//src/org/nevec/rjm/BigSurd.java=UTF-8 +encoding//src/org/nevec/rjm/BigSurdVec.java=UTF-8 +encoding//src/org/nevec/rjm/NumeroAvanzato.java=UTF-8 +encoding//src/org/nevec/rjm/NumeroAvanzatoVec.java=UTF-8 +encoding//src/org/warpgate/pi/calculator/Main.java=UTF-8 +encoding//src/org/warpgate/pi/calculator/Parentesi.java=UTF-8 +encoding//src/org/warpgate/pi/calculator/Radice.java=UTF-8 +encoding//src/org/warpgate/pi/calculator/RadiceQuadrata.java=UTF-8 +encoding//src/org/warpgate/pi/calculator/Simboli.java=UTF-8 diff --git a/out.txt b/out.txt deleted file mode 100644 index 79650eae..00000000 --- a/out.txt +++ /dev/null @@ -1,88 +0,0 @@ -•Analyzing expression:((+35(2√7))+(9(2√13)))/21 - •Added implicit multiplications:((35*(2√7))+(9*(2√13)))/21 - •Subdivision in classes: - •Analyzing expression:(35*(2√7))+(9*(2√13)) - •Added implicit multiplications:(35*(2√7))+(9*(2√13)) - •Subdivision in classes: - •Analyzing expression:35*(2√7) - •Added implicit multiplications:35*(2√7) - •Subdivision in classes: - •Added variable to expression:35 - •Added variable to expression:* - •Analyzing expression:2√7 - •Subdivision in classes: - •Added variable to expression:2 - •Added variable to expression:√ - •Added variable to expression:7 - •Finished the subdivision in classes. - •Pushing classes... - •Correcting classes: - •Set variable to expression:√ - var1=2 - var2=7 - (result)=2√7 - •Finished correcting classes. - •Result:2√7 - •Added variable to expression:Parentesi - •Finished the subdivision in classes. - •Pushing classes... - •Correcting classes: - •Set variable to expression:* - var1=35 - var2=2√7 - (result)=35*(2√7) - •Finished correcting classes. - •Result:35*(2√7) - •Added variable to expression:Parentesi - •Added variable to expression:+ - •Analyzing expression:9*(2√13) - •Added implicit multiplications:9*(2√13) - •Subdivision in classes: - •Added variable to expression:9 - •Added variable to expression:* - •Analyzing expression:2√13 - •Subdivision in classes: - •Added variable to expression:2 - •Added variable to expression:√ - •Added variable to expression:13 - •Finished the subdivision in classes. - •Pushing classes... - •Correcting classes: - •Set variable to expression:√ - var1=2 - var2=13 - (result)=2√13 - •Finished correcting classes. - •Result:2√13 - •Added variable to expression:Parentesi - •Finished the subdivision in classes. - •Pushing classes... - •Correcting classes: - •Set variable to expression:* - var1=9 - var2=2√13 - (result)=9*(2√13) - •Finished correcting classes. - •Result:9*(2√13) - •Added variable to expression:Parentesi - •Finished the subdivision in classes. - •Pushing classes... - •Correcting classes: - •Set variable to expression:+ - var1=35*(2√7) - var2=9*(2√13) - (result)=35*(2√7)+9*(2√13) - •Finished correcting classes. - •Result:35*(2√7)+9*(2√13) - •Added variable to expression:Parentesi - •Added variable to expression:/ - •Added variable to expression:21 - •Finished the subdivision in classes. - •Pushing classes... - •Correcting classes: - •Set variable to expression:/ - var1=35*(2√7)+9*(2√13) - var2=21 - (result)=(35*(2√7)+9*(2√13))/21 - •Finished correcting classes. - •Result:(35*(2√7)+9*(2√13))/21 diff --git a/src/org/nevec/rjm/Bernoulli.java b/src/org/nevec/rjm/Bernoulli.java index 20bd87f2..1563c6cf 100644 --- a/src/org/nevec/rjm/Bernoulli.java +++ b/src/org/nevec/rjm/Bernoulli.java @@ -3,6 +3,8 @@ package org.nevec.rjm ; import java.math.BigInteger; import java.util.Vector; +import org.warpgate.pi.calculator.Errore; + /** Bernoulli numbers. * @since 2006-06-25 @@ -44,8 +46,9 @@ public class Bernoulli /** The Bernoulli number at the index provided. * @param n the index, non-negative. * @return the B_0=1 for n=0, B_1=-1/2 for n=1, B_2=1/6 for n=2 etc + * @throws Errore */ - public Rational at(int n) + public Rational at(int n) throws Errore { if ( n == 1) return(new Rational(-1,2)) ; @@ -67,7 +70,7 @@ public class Bernoulli * @param n The index of the Bernoulli number. * @return The Bernoulli number at n. */ - private Rational doubleSum(int n) + private Rational doubleSum(int n) throws Errore { Rational resul = Rational.ZERO ; for(int k=0 ; k <= n ; k++) diff --git a/src/org/nevec/rjm/BigDecimalMath.java b/src/org/nevec/rjm/BigDecimalMath.java index d5085536..a08ac881 100644 --- a/src/org/nevec/rjm/BigDecimalMath.java +++ b/src/org/nevec/rjm/BigDecimalMath.java @@ -5,6 +5,8 @@ import java.math.BigInteger; import java.math.MathContext; import java.security.ProviderException; +import org.warpgate.pi.calculator.Errore; + /** BigDecimal special functions. * A Java Math.BigDecimal Implementation of Core Mathematical Functions @@ -120,9 +122,10 @@ public class BigDecimalMath /** Euler's constant. * @param mc The required precision of the result. * @return 3.14159... + * @throws Errore * @since 2009-05-29 */ - static public BigDecimal pi(final MathContext mc) + static public BigDecimal pi(final MathContext mc) throws Errore { /* look it up if possible */ if ( mc.getPrecision() < PI.precision() ) @@ -140,9 +143,10 @@ public class BigDecimalMath /** Euler-Mascheroni constant. * @param mc The required precision of the result. * @return 0.577... + * @throws Errore * @since 2009-08-13 */ - static public BigDecimal gamma(MathContext mc) + static public BigDecimal gamma(MathContext mc) throws Errore { /* look it up if possible */ if ( mc.getPrecision() < GAMMA.precision() ) @@ -212,12 +216,11 @@ public class BigDecimalMath * smaller than the precision requested. The relative correction is 1-x/s^2, * (actually half of this, which we use for a little bit of additional protection). */ - if ( Math.abs(BigDecimal.ONE.subtract(x.divide(s.pow(2,locmc),locmc)).doubleValue()) < eps) + if ( Math.abs(BigDecimal.ONE.subtract(x.divide(s.pow(2,locmc),locmc)).doubleValue()) <= eps) break ; s = s.add(x.divide(s,locmc)).divide(half,locmc) ; - /* debugging - * System.out.println("itr "+x.round(locmc).toString() + " " + s.round(locmc).toString()) ; - */ + /* debugging*/ + System.out.println("itr "+x.round(locmc).toString() + " " + s.round(locmc).toString()) ; } return s ; } /* BigDecimalMath.sqrt */ @@ -559,8 +562,9 @@ public class BigDecimalMath * @return ln(n). * @since 2009-08-08 * @author Richard J. Mathar + * @throws Errore */ - static public BigDecimal log(int n, final MathContext mc) + static public BigDecimal log(int n, final MathContext mc) throws Errore { /* the value is undefined if x is negative. */ @@ -938,9 +942,10 @@ public class BigDecimalMath /** Trigonometric sine. * @param x The argument in radians. * @return sin(x) in the range -1 to 1. + * @throws Errore * @since 2009-06-01 */ - static public BigDecimal sin(final BigDecimal x) + static public BigDecimal sin(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ZERO) < 0) return sin(x.negate()).negate() ; @@ -1024,9 +1029,10 @@ public class BigDecimalMath /** Trigonometric cosine. * @param x The argument in radians. * @return cos(x) in the range -1 to 1. + * @throws Errore * @since 2009-06-01 */ - static public BigDecimal cos(final BigDecimal x) + static public BigDecimal cos(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ZERO) < 0) return cos(x.negate()); @@ -1110,8 +1116,9 @@ public class BigDecimalMath /** The trigonometric tangent. * @param x the argument in radians. * @return the tan(x) + * @throws Errore */ - static public BigDecimal tan(final BigDecimal x) + static public BigDecimal tan(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ZERO) == 0 ) return BigDecimal.ZERO ; @@ -1176,9 +1183,10 @@ public class BigDecimalMath /** The trigonometric co-tangent. * @param x the argument in radians. * @return the cot(x) + * @throws Errore * @since 2009-07-31 */ - static public BigDecimal cot(final BigDecimal x) + static public BigDecimal cot(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ZERO) == 0 ) { @@ -1240,8 +1248,9 @@ public class BigDecimalMath /** The inverse trigonometric sine. * @param x the argument. * @return the arcsin(x) in radians. + * @throws Errore */ - static public BigDecimal asin(final BigDecimal x) + static public BigDecimal asin(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ONE) > 0 || x.compareTo(BigDecimal.ONE.negate()) < 0 ) { @@ -1346,9 +1355,10 @@ public class BigDecimalMath /** The inverse trigonometric cosine. * @param x the argument. * @return the arccos(x) in radians. + * @throws Errore * @since 2009-09-29 */ - static public BigDecimal acos(final BigDecimal x) + static public BigDecimal acos(final BigDecimal x) throws Errore { /* Essentially forwarded to pi/2 - asin(x) */ @@ -1374,9 +1384,10 @@ public class BigDecimalMath /** The inverse trigonometric tangent. * @param x the argument. * @return the principal value of arctan(x) in radians in the range -pi/2 to +pi/2. + * @throws Errore * @since 2009-08-03 */ - static public BigDecimal atan(final BigDecimal x) + static public BigDecimal atan(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ZERO) < 0 ) { @@ -1467,9 +1478,10 @@ public class BigDecimalMath * @param x The argument. * @return The cosh(x) = (exp(x)+exp(-x))/2 . * @author Richard J. Mathar + * @throws Errore * @since 2009-08-19 */ - static public BigDecimal cosh(final BigDecimal x) + static public BigDecimal cosh(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ZERO) < 0) return cos(x.negate()); @@ -1533,9 +1545,10 @@ public class BigDecimalMath * @param x the argument. * @return the sinh(x) = (exp(x)-exp(-x))/2 . * @author Richard J. Mathar + * @throws Errore * @since 2009-08-19 */ - static public BigDecimal sinh(final BigDecimal x) + static public BigDecimal sinh(final BigDecimal x) throws Errore { if ( x.compareTo(BigDecimal.ZERO) < 0) return sinh(x.negate()).negate() ; @@ -1688,9 +1701,10 @@ public class BigDecimalMath /** The Gamma function. * @param x The argument. * @return Gamma(x). + * @throws Errore * @since 2009-08-06 */ - static public BigDecimal Gamma(final BigDecimal x) + static public BigDecimal Gamma(final BigDecimal x) throws Errore { /* reduce to interval near 1.0 with the functional relation, Abramowitz-Stegun 6.1.33 */ @@ -1778,9 +1792,10 @@ public class BigDecimalMath * @param q The argument. * @param mc The required accuracy in the result. * @return Gamma(x). + * @throws Errore * @since 2010-05-26 */ - static public BigDecimal Gamma(final Rational q, final MathContext mc) + static public BigDecimal Gamma(final Rational q, final MathContext mc) throws Errore { if ( q.isBigInteger() ) { @@ -1878,9 +1893,10 @@ public class BigDecimalMath /** Reduce value to the interval [0,2*Pi]. * @param x the original value * @return the value modulo 2*pi in the interval from 0 to 2*pi. + * @throws Errore * @since 2009-06-01 */ - static public BigDecimal mod2pi(BigDecimal x) + static public BigDecimal mod2pi(BigDecimal x) throws Errore { /* write x= 2*pi*k+r with the precision in r defined by the precision of x and not * compromised by the precision of 2*pi, so the ulp of 2*pi*k should match the ulp of x. @@ -1914,9 +1930,10 @@ public class BigDecimalMath /** Reduce value to the interval [-Pi/2,Pi/2]. * @param x The original value * @return The value modulo pi, shifted to the interval from -Pi/2 to Pi/2. + * @throws Errore * @since 2009-07-31 */ - static public BigDecimal modpi(BigDecimal x) + static public BigDecimal modpi(BigDecimal x) throws Errore { /* write x= pi*k+r with the precision in r defined by the precision of x and not * compromised by the precision of pi, so the ulp of pi*k should match the ulp of x. @@ -1954,9 +1971,10 @@ public class BigDecimalMath * @param n The positive integer argument. * @param mc Specification of the accuracy of the result. * @return zeta(n). + * @throws Errore * @since 2009-08-05 */ - static public BigDecimal zeta(final int n, final MathContext mc) + static public BigDecimal zeta(final int n, final MathContext mc) throws Errore { if( n <= 0 ) throw new ProviderException("Not implemented: zeta at negative argument "+n) ; @@ -2117,9 +2135,10 @@ public class BigDecimalMath /** Riemann zeta function. * @param n The positive integer argument. * @return zeta(n)-1. + * @throws Errore * @since 2009-08-20 */ - static public double zeta1(final int n) + static public double zeta1(final int n) throws Errore { /* precomputed static table in double precision */ @@ -2208,9 +2227,10 @@ public class BigDecimalMath * @param x The main argument. * @return psi(x). * The error is sometimes up to 10 ulp, where AS 6.3.15 suffers from cancellation of digits and psi=0 + * @throws Errore * @since 2009-08-26 */ - static public double psi(final double x) + static public double psi(final double x) throws Errore { /* the single positive zero of psi(x) */ @@ -2280,10 +2300,11 @@ public class BigDecimalMath * @param a The vector of 8 integer arguments * @param mc Specification of the accuracy of the result * @return S_(n,p)(a) + * @throws Errore * @since 2009-08-09 * @see arXiv:math/9803067 */ - static protected BigDecimal broadhurstBBP(final int n, final int p, final int a[], MathContext mc) + static protected BigDecimal broadhurstBBP(final int n, final int p, final int a[], MathContext mc) throws Errore { /* Explore the actual magnitude of the result first with a quick estimate. */ diff --git a/src/org/nevec/rjm/BigIntegerMath.java b/src/org/nevec/rjm/BigIntegerMath.java index 6272ea61..0c04f86a 100644 --- a/src/org/nevec/rjm/BigIntegerMath.java +++ b/src/org/nevec/rjm/BigIntegerMath.java @@ -3,6 +3,8 @@ package org.nevec.rjm ; import java.math.BigInteger; import java.util.Vector; +import org.warpgate.pi.calculator.Errore; + /** BigInteger special functions and Number theory. * @since 2009-08-06 @@ -365,8 +367,9 @@ public class BigIntegerMath * @return The vector of x in A*x=rhs. * @since 2010-08-28 * @author Richard J. Mathar + * @throws Errore */ - static public Rational[] solve(final BigInteger[][]A, final BigInteger[] rhs) throws ArithmeticException + static public Rational[] solve(final BigInteger[][]A, final BigInteger[] rhs) throws ArithmeticException, Errore { final int rL = A.length ; @@ -483,9 +486,10 @@ public class BigIntegerMath * @return t(n,k) * @since 2009-08-06 * @author Richard J. Mathar + * @throws Errore * @see P. L. Butzer et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488 */ - static public Rational centrlFactNumt(int n,int k) + static public Rational centrlFactNumt(int n,int k) throws Errore { if ( k > n || k < 0 || ( k % 2 ) != (n % 2) ) return Rational.ZERO ; diff --git a/src/org/nevec/rjm/BigIntegerPoly.java b/src/org/nevec/rjm/BigIntegerPoly.java index d7d94cea..444234c9 100644 --- a/src/org/nevec/rjm/BigIntegerPoly.java +++ b/src/org/nevec/rjm/BigIntegerPoly.java @@ -5,6 +5,8 @@ import java.math.BigInteger; import java.util.Scanner; import java.util.Vector; +import org.warpgate.pi.calculator.Errore; + /** Polynomial with integer coefficients. * Alternatively to be interpreted as a sequence which has the polynomial as an (approximate) * generating function. @@ -519,9 +521,10 @@ public class BigIntegerPoly implements Cloneable * @return A (potentially empty) vector of factors, without multiplicity. * Only factors with non-zero absolute coefficient are generated. * This means the factors are of the form x^2+a*x+b=0 with nonzero b. + * @throws Errore * @since 2012-03-01 */ - protected Vector i2roots() + protected Vector i2roots() throws Errore { /* The vector of the factors to be returned */ @@ -605,9 +608,10 @@ public class BigIntegerPoly implements Cloneable /** Factorization into integer polynomials. * The current factorization detects only factors which are polynomials of order up to 2. * @return The vector of factors. Factors with higher multiplicity are represented by repetition. + * @throws Errore * @since 2012-03-01 */ - public Vector ifactor() + public Vector ifactor() throws Errore { /* this ought be entirely rewritten in terms of the LLL algorithm */ diff --git a/src/org/nevec/rjm/BigSurd.java b/src/org/nevec/rjm/BigSurd.java index 339a408a..a40097c2 100644 --- a/src/org/nevec/rjm/BigSurd.java +++ b/src/org/nevec/rjm/BigSurd.java @@ -5,6 +5,7 @@ import java.math.BigInteger; import java.math.MathContext; import java.security.ProviderException; +import org.warpgate.pi.calculator.Errore; import org.warpgate.pi.calculator.Utils; /** Square roots on the real line. @@ -56,8 +57,12 @@ public class BigSurd implements Cloneable, Comparable if ( b.signum() < 0 ) throw new ProviderException("Not implemented: imaginary surds") ; this.disc = b ; - normalize() ; - normalizeG() ; + try { + normalize() ; + normalizeG() ; + } catch (Errore e) { + e.printStackTrace(); + } } /** ctor given the numerator and denominator of the root. @@ -175,9 +180,10 @@ public class BigSurd implements Cloneable, Comparable /** Divide by another square root. * @param val A second number of this type. * @return The value of this/val + * @throws Errore * @since 2011-02-12 */ - public BigSurd divide(final BigSurd val) + public BigSurd divide(final BigSurd val) throws Errore { if( val.signum() == 0 ) throw new ArithmeticException("Dividing "+ toFancyString() + " through zero.") ; @@ -218,9 +224,10 @@ public class BigSurd implements Cloneable, Comparable /** Divide by an integer. * @param val a second number. * @return the value of this/val + * @throws Errore * @since 2011-02-12 */ - public BigSurd divide(final BigInteger val) + public BigSurd divide(final BigInteger val) throws Errore { if( val.signum() == 0 ) throw new ArithmeticException("Dividing "+ toFancyString() + " through zero.") ; @@ -230,9 +237,10 @@ public class BigSurd implements Cloneable, Comparable /** Divide by an integer. * @param val A second number. * @return The value of this/val + * @throws Errore * @since 2011-02-12 */ - public BigSurd divide(int val) + public BigSurd divide(int val) throws Errore { if( val == 0 ) throw new ArithmeticException("Dividing "+ toFancyString() + " through zero.") ; @@ -384,9 +392,10 @@ System.out.println("dv sq " + res) ; } /* BigSurd.signum */ /** Normalize to squarefree discriminant. + * @throws Errore * @since 2011-02-12 */ - protected void normalize() + protected void normalize() throws Errore { /* Move squares out of the numerator and denominator of the discriminant */ @@ -418,9 +427,10 @@ System.out.println("dv sq " + res) ; } /* BigSurd.normalize */ /** Normalize to coprime numerator and denominator in prefactor and discriminant + * @throws Errore * @since 2011-02-12 */ - protected void normalizeG() + protected void normalizeG() throws Errore { /* Is there a common factor between the numerator of the prefactor * and the denominator of the discriminant ? diff --git a/src/org/nevec/rjm/BigSurdVec.java b/src/org/nevec/rjm/BigSurdVec.java index 68c1d7d4..c917a863 100644 --- a/src/org/nevec/rjm/BigSurdVec.java +++ b/src/org/nevec/rjm/BigSurdVec.java @@ -5,6 +5,7 @@ import java.math.BigInteger; import java.math.MathContext; import java.util.Vector; +import org.warpgate.pi.calculator.Errore; import org.warpgate.pi.calculator.Utils; /** @@ -66,16 +67,22 @@ public class BigSurdVec implements Comparable { terms = new Vector(2); terms.add(a); terms.add(b); - normalize(); + try { + normalize(); + } catch (Errore e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } /* ctor */ /** * Combine terms that can be written as a single surd. This unites for * example the terms sqrt(90) and sqrt(10) to 4*sqrt(10). + * @throws Errore * * @since 2012-02-15 */ - protected void normalize() { + protected void normalize() throws Errore { /* * nothing to be done if at most one term */ @@ -135,8 +142,15 @@ public class BigSurdVec implements Comparable { * @since 2012-02-15 */ public int compareTo(BigSurdVec oth) { - final BigSurdVec diff = this.subtract(oth); - return diff.signum(); + BigSurdVec diff; + try { + diff = this.subtract(oth); + return diff.signum(); + } catch (Errore e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return 0; + } } /* compareTo */ /** @@ -144,9 +158,10 @@ public class BigSurdVec implements Comparable { * equal to or larger than zero. * * @return 0 or +-1. + * @throws Errore * @since 2012-02-15 */ - public int signum() { + public int signum() throws Errore { /* * the case of zero is unique, because no (reduced) vector of surds * other than the one element 0 itself can add/subtract to zero. @@ -289,8 +304,9 @@ public class BigSurdVec implements Comparable { * @param val * The value to be added to this. * @return The new value representing this+val. + * @throws Errore */ - public BigSurdVec add(final BigSurdVec val) { + public BigSurdVec add(final BigSurdVec val) throws Errore { BigSurdVec sum = new BigSurdVec(); /* * concatenate the vectors and eliminate common overlaps @@ -315,8 +331,9 @@ public class BigSurdVec implements Comparable { * @param val * The value to be added to this. * @return The new value representing this+val. + * @throws Errore */ - public BigSurdVec add(final BigSurd val) { + public BigSurdVec add(final BigSurd val) throws Errore { BigSurdVec sum = new BigSurdVec(); /* * concatenate the vectors and eliminate common overlaps @@ -333,8 +350,9 @@ public class BigSurdVec implements Comparable { * @param val * The value to be subtracted from this. * @return The new value representing this-val. + * @throws Errore */ - public BigSurdVec subtract(final BigSurdVec val) { + public BigSurdVec subtract(final BigSurdVec val) throws Errore { BigSurdVec sum = new BigSurdVec(); /* * concatenate the vectors and eliminate common overlaps @@ -352,8 +370,9 @@ public class BigSurdVec implements Comparable { * @param val * The value to be subtracted from this. * @return The new value representing this-val. + * @throws Errore */ - public BigSurdVec subtract(final BigSurd val) { + public BigSurdVec subtract(final BigSurd val) throws Errore { BigSurdVec sum = new BigSurdVec(); /* * concatenate the vectors and eliminate common overlaps @@ -388,9 +407,10 @@ public class BigSurdVec implements Comparable { * Compute the square. * * @return this value squared. + * @throws Errore * @since 2012-02-15 */ - public BigSurdVec sqr() { + public BigSurdVec sqr() throws Errore { /* * Binomial expansion. First the sum of the terms squared, then 2 times * the mixed products. @@ -411,9 +431,10 @@ public class BigSurdVec implements Comparable { * @param val * a second number of this type. * @return the product of this with the val. + * @throws Errore * @since 2011-02-12 */ - public BigSurdVec multiply(final BigSurd val) { + public BigSurdVec multiply(final BigSurd val) throws Errore { BigSurdVec resul = new BigSurdVec(); for (BigSurd s : terms) resul.terms.add(s.multiply(val)); @@ -421,7 +442,7 @@ public class BigSurdVec implements Comparable { return resul; } /* multiply */ - public BigSurdVec multiply(final BigSurdVec val) { + public BigSurdVec multiply(final BigSurdVec val) throws Errore { BigSurdVec resul = new BigSurdVec(); for (BigSurd s : terms) { resul.terms.add(s); @@ -432,7 +453,7 @@ public class BigSurdVec implements Comparable { return resul; } /* multiply */ - public BigSurdVec divide(final BigSurd val) { + public BigSurdVec divide(final BigSurd val) throws Errore { BigSurdVec resul = new BigSurdVec(); for (BigSurd s : terms) resul.terms.add(s.divide(val)); @@ -440,7 +461,7 @@ public class BigSurdVec implements Comparable { return resul; } /* multiply */ - public BigSurdVec divide(final BigSurdVec val) { + public BigSurdVec divide(final BigSurdVec val) throws Errore { BigSurdVec resul = new BigSurdVec(); resul.terms = terms; for (BigSurd s : val.terms) { @@ -576,16 +597,16 @@ public class BigSurdVec implements Comparable { if (numerator.compareTo(BigInteger.ONE) != 0) { s += numerator.toString(); s += "*"; - s += "("; + //s += "("; Radice quadrata. non servono le parentesi. } - s += "2√"; + s += "Ⓐ"; if (bs.disc.isInteger()) { s += bs.disc.toString(); } else { s += "("+bs.disc.toString()+")"; } if (numerator.compareTo(BigInteger.ONE) != 0) { - s += ")"; + //s += ")"; Radice quadrata. non servono le parentesi. } } } diff --git a/src/org/nevec/rjm/Ifactor.java b/src/org/nevec/rjm/Ifactor.java index 6e1ad348..2b958be9 100644 --- a/src/org/nevec/rjm/Ifactor.java +++ b/src/org/nevec/rjm/Ifactor.java @@ -4,6 +4,8 @@ import java.math.BigInteger; import java.util.Collections; import java.util.Vector; +import org.warpgate.pi.calculator.Errore; + /** Factored integers. * This class contains a non-negative integer with the prime factor decomposition attached. * @since 2006-08-14 @@ -423,9 +425,10 @@ public class Ifactor implements Cloneable, Comparable * @return n^(1/r). * The return value falls into the Ifactor class if r is positive, but if r is negative * a Rational type is needed. + * @throws Errore * @since 2009-05-18 */ - public Rational root(final int r) throws ArithmeticException + public Rational root(final int r) throws ArithmeticException, Errore { if ( r == 0 ) throw new ArithmeticException("Cannot pull zeroth root of "+ toString()) ; diff --git a/src/org/nevec/rjm/RatPoly.java b/src/org/nevec/rjm/RatPoly.java index e01f082f..027c77b9 100644 --- a/src/org/nevec/rjm/RatPoly.java +++ b/src/org/nevec/rjm/RatPoly.java @@ -7,6 +7,8 @@ import java.util.Random; import java.util.Scanner; import java.util.Vector; +import org.warpgate.pi.calculator.Errore; + /** A one-parameter polynomial with rational coefficients. * Alternatively to be interpreted as a sequence which has the polynomial as an (approximate) * generating function. @@ -61,9 +63,10 @@ class RatPoly * @param A the list of values in the numerator of AFB * @param B the list of values in the denominator of AFB * @param nmax the order of the truncated polynomial representation + * @throws Errore * @since 2008-11-13 */ - public RatPoly(final Vector A, final Vector B, int nmax) + public RatPoly(final Vector A, final Vector B, int nmax) throws Errore { /* To allow common initialization with the signature below, * the main body is assembled in a separate function. @@ -77,9 +80,10 @@ class RatPoly * At least one of these values must be a negative integer, which implicitly determines * the order of the new polynomial. * @param B the list of values in the denominator of AFB + * @throws Errore * @since 2009-08-05 */ - public RatPoly(final Vector A, final Vector B) + public RatPoly(final Vector A, final Vector B) throws Errore { BigInteger Nmax = BigInteger.ONE.negate() ; for(int j=0; j < A.size() ; j++) @@ -103,9 +107,10 @@ class RatPoly * @param A the list of values in the numerator of AFB * @param B the list of values in the denominator of AFB * @param nmax the order of the truncated polynomial representation + * @throws Errore * @since 2008-11-13 */ - protected void init(final Vector A, final Vector B, int nmax) + protected void init(final Vector A, final Vector B, int nmax) throws Errore { a = new Vector() ; Factorial f=new Factorial() ; @@ -370,9 +375,10 @@ class RatPoly * term that remains undetermined based on the current number of coefficients. * @param r the exponent of the power * @return This^r . + * @throws Errore * @since 2009-05-18 */ - public RatPoly pow(final Rational r) throws ArithmeticException + public RatPoly pow(final Rational r) throws ArithmeticException, Errore { /* split (a0+a1*x+a2*x^2+...)^r = a0^r*(1+a1/a0*r+a2/a0*r^2+..)^r */ @@ -443,9 +449,10 @@ class RatPoly /** Divide by a constant. * @param val the constant through which the coefficients will be divided. * @return the Taylor expansion of this/val . + * @throws Errore * @since 2009-05-18 */ - public RatPoly divide(final Rational val) + public RatPoly divide(final Rational val) throws Errore { if ( val.compareTo(Rational.ZERO) != 0 ) { @@ -462,8 +469,9 @@ class RatPoly * @param val the other polynomial * @param nmax the maximum degree of the Taylor expansion of the result. * @return the Taylor expansion of this/val up to degree nmax. + * @throws Errore */ - public RatPoly divide(final RatPoly val,int nmax) + public RatPoly divide(final RatPoly val,int nmax) throws Errore { RatPoly num = this ; RatPoly denom = val ; @@ -501,9 +509,10 @@ class RatPoly * @return A vector with [0] containg the polynomial of degree which is the * difference of thisdegree and the degree of val. [1] the remainder polynomial. * This = returnvalue[0] + returnvalue[1]/val . + * @throws Errore * @since 2012-03-01 */ - public RatPoly[] divideAndRemainder(final RatPoly val) + public RatPoly[] divideAndRemainder(final RatPoly val) throws Errore { RatPoly[] ret = new RatPoly[2] ; /* remove any high-order zeros @@ -648,9 +657,10 @@ class RatPoly /** Scale coefficients such that the coefficient in front of the maximum degree is unity. * @return The scaled polynomial + * @throws Errore * @since 2008-10-26 */ - public RatPoly monic() + public RatPoly monic() throws Errore { RatPoly m = new RatPoly() ; final int d = degree() ; @@ -776,9 +786,10 @@ class RatPoly /** Generate the roots of the polynomial in floating point arithmetic. * @see Durand Kerner method * @param the number of floating point digits + * @throws Errore * @since 2008-10-26 */ - public Vector roots(int digits) + public Vector roots(int digits) throws Errore { RatPoly mon = monic() ; diff --git a/src/org/nevec/rjm/Rational.java b/src/org/nevec/rjm/Rational.java index e2f1dd74..78034164 100644 --- a/src/org/nevec/rjm/Rational.java +++ b/src/org/nevec/rjm/Rational.java @@ -1,747 +1,869 @@ -package org.nevec.rjm ; +package org.nevec.rjm; import java.math.BigDecimal; import java.math.BigInteger; import java.math.MathContext; import java.math.RoundingMode; -/** Fractions (rational numbers). -* They are divisions of two BigInteger numbers, reduced to coprime -* numerator and denominator. -* @since 2006-06-25 -* @author Richard J. Mathar -*/ -public class Rational implements Cloneable, Comparable -{ - /** numerator - */ - BigInteger a ; +import org.warpgate.pi.calculator.Errore; +import org.warpgate.pi.calculator.Errori; - /** denominator, always larger than zero. - */ - BigInteger b ; +/** + * Fractions (rational numbers). They are divisions of two BigInteger numbers, + * reduced to coprime numerator and denominator. + * + * @since 2006-06-25 + * @author Richard J. Mathar + */ +public class Rational implements Cloneable, Comparable { + /** + * numerator + */ + BigInteger a; - /** The maximum and minimum value of a standard Java integer, 2^31. - * @since 2009-05-18 - */ - static public BigInteger MAX_INT = new BigInteger("2147483647") ; - static public BigInteger MIN_INT = new BigInteger("-2147483648") ; + /** + * denominator, always larger than zero. + */ + BigInteger b; - /** The constant 1. - */ - public static Rational ONE = new Rational(1,1) ; - /** The constant 0. - */ - static public Rational ZERO = new Rational() ; + /** + * The maximum and minimum value of a standard Java integer, 2^31. + * + * @since 2009-05-18 + */ + static public BigInteger MAX_INT = new BigInteger("2147483647"); + static public BigInteger MIN_INT = new BigInteger("-2147483648"); - /** The constant 1/2 - * @since 2010-05-25 - */ - static public Rational HALF = new Rational(1,2) ; + /** + * The constant 1. + */ + public static Rational ONE = new Rational(1, 1); + /** + * The constant 0. + */ + static public Rational ZERO = new Rational(); - /** Default ctor, which represents the zero. - * @since 2007-11-17 - */ - public Rational() - { - a = BigInteger.ZERO ; - b = BigInteger.ONE ; - } + /** + * The constant 1/2 + * + * @since 2010-05-25 + */ + static public Rational HALF = new Rational(1, 2); - /** ctor from a numerator and denominator. - * @param a the numerator. - * @param b the denominator. - */ - public Rational(BigInteger a, BigInteger b) - { - this.a = a ; - this.b = b ; - normalize() ; - } + /** + * Default ctor, which represents the zero. + * + * @since 2007-11-17 + */ + public Rational() { + a = BigInteger.ZERO; + b = BigInteger.ONE; + } - /** ctor from a numerator. - * @param a the BigInteger. - */ - public Rational(BigInteger a) - { - this.a = a ; - b = new BigInteger("1") ; - } + /** + * ctor from a numerator and denominator. + * + * @param a + * the numerator. + * @param b + * the denominator. + */ + public Rational(BigInteger a, BigInteger b) { + this.a = a; + this.b = b; + normalize(); + } - /** ctor from a numerator and denominator. - * @param a the numerator. - * @param b the denominator. - */ - public Rational(int a, int b) - { - this(new BigInteger(""+a),new BigInteger(""+b)) ; - } + /** + * ctor from a numerator. + * + * @param a + * the BigInteger. + */ + public Rational(BigInteger a) { + this.a = a; + b = new BigInteger("1"); + } - /** ctor from an integer. - * @param n the integer to be represented by the new instance. - * @since 2010-07-18 - */ - public Rational(int n) - { - this(n,1) ; - } + /** + * ctor from a numerator and denominator. + * + * @param a + * the numerator. + * @param b + * the denominator. + */ + public Rational(int a, int b) { + this(new BigInteger("" + a), new BigInteger("" + b)); + } - /** ctor from a string representation. - * @param str the string. - * This either has a slash in it, separating two integers, or, if there is no slash, - * is representing the numerator with implicit denominator equal to 1. - * Warning: this does not yet test for a denominator equal to zero - */ - public Rational(String str) throws NumberFormatException - { - this(str,10) ; - } + /** + * ctor from an integer. + * + * @param n + * the integer to be represented by the new instance. + * @since 2010-07-18 + */ + public Rational(int n) { + this(n, 1); + } - /** ctor from a string representation in a specified base. - * @param str the string. - * This either has a slash in it, separating two integers, or, if there is no slash, - * is just representing the numerator. - * @param radix the number base for numerator and denominator - * Warning: this does not yet test for a denominator equal to zero - */ - public Rational(String str, int radix) throws NumberFormatException - { - int hasslah = str.indexOf("/") ; - if ( hasslah == -1 ) - { - a = new BigInteger(str,radix) ; - b = new BigInteger("1",radix) ; - /* no normalization necessary here */ - } - else - { - /* create numerator and denominator separately - */ - a = new BigInteger(str.substring(0,hasslah),radix) ; - b = new BigInteger(str.substring(hasslah+1),radix) ; - normalize() ; - } - } + /** + * ctor from a string representation. + * + * @param str + * the string. This either has a slash in it, separating two + * integers, or, if there is no slash, is representing the + * numerator with implicit denominator equal to 1. Warning: this + * does not yet test for a denominator equal to zero + */ + public Rational(String str) { + this(str, 10); + } - /** Create a copy. - * @since 2008-11-07 - */ - public Rational clone() - { - /* protected access means this does not work - * return new Rational(a.clone(), b.clone()) ; - */ - BigInteger aclon = new BigInteger(""+a) ; - BigInteger bclon = new BigInteger(""+b) ; - return new Rational(aclon,bclon) ; - } /* Rational.clone */ + /** + * ctor from a string representation in a specified base. + * + * @param str + * the string. This either has a slash in it, separating two + * integers, or, if there is no slash, is just representing the + * numerator. + * @param radix + * the number base for numerator and denominator Warning: this + * does not yet test for a denominator equal to zero + */ + public Rational(String str, int radix) { + int hasslah = str.indexOf("/"); + if (hasslah == -1) { + a = new BigInteger(str, radix); + b = new BigInteger("1", radix); + /* no normalization necessary here */ + } else { + /* + * create numerator and denominator separately + */ + a = new BigInteger(str.substring(0, hasslah), radix); + b = new BigInteger(str.substring(hasslah + 1), radix); + normalize(); + } + } - /** Multiply by another fraction. - * @param val a second rational number. - * @return the product of this with the val. - */ - public Rational multiply(final Rational val) - { - BigInteger num = a.multiply(val.a) ; - BigInteger deno = b.multiply(val.b) ; - /* Normalization to an coprime format will be done inside - * the ctor() and is not duplicated here. - */ - return ( new Rational(num,deno) ) ; - } /* Rational.multiply */ + /** + * Create a copy. + * + * @since 2008-11-07 + */ + public Rational clone() { + /* + * protected access means this does not work return new + * Rational(a.clone(), b.clone()) ; + */ + BigInteger aclon = new BigInteger("" + a); + BigInteger bclon = new BigInteger("" + b); + return new Rational(aclon, bclon); + } /* Rational.clone */ - /** Multiply by a BigInteger. - * @param val a second number. - * @return the product of this with the value. - */ - public Rational multiply(final BigInteger val) - { - Rational val2 = new Rational(val,BigInteger.ONE) ; - return ( multiply(val2) ) ; - } /* Rational.multiply */ + /** + * Multiply by another fraction. + * + * @param val + * a second rational number. + * @return the product of this with the val. + */ + public Rational multiply(final Rational val) { + BigInteger num = a.multiply(val.a); + BigInteger deno = b.multiply(val.b); + /* + * Normalization to an coprime format will be done inside the ctor() and + * is not duplicated here. + */ + return (new Rational(num, deno)); + } /* Rational.multiply */ - /** Multiply by an integer. - * @param val a second number. - * @return the product of this with the value. - */ - public Rational multiply(final int val) - { - BigInteger tmp = new BigInteger(""+val) ; - return multiply(tmp) ; - } /* Rational.multiply */ + /** + * Multiply by a BigInteger. + * + * @param val + * a second number. + * @return the product of this with the value. + */ + public Rational multiply(final BigInteger val) { + Rational val2 = new Rational(val, BigInteger.ONE); + return (multiply(val2)); + } /* Rational.multiply */ - /** Power to an integer. - * @param exponent the exponent. - * @return this value raised to the power given by the exponent. - * If the exponent is 0, the value 1 is returned. - */ - public Rational pow(int exponent) - { - if ( exponent == 0 ) - return new Rational(1,1) ; + /** + * Multiply by an integer. + * + * @param val + * a second number. + * @return the product of this with the value. + */ + public Rational multiply(final int val) { + BigInteger tmp = new BigInteger("" + val); + return multiply(tmp); + } /* Rational.multiply */ - BigInteger num = a.pow(Math.abs(exponent)) ; - BigInteger deno = b.pow(Math.abs(exponent)) ; - if ( exponent > 0 ) - return ( new Rational(num,deno) ) ; - else - return ( new Rational(deno,num) ) ; - } /* Rational.pow */ + /** + * Power to an integer. + * + * @param exponent + * the exponent. + * @return this value raised to the power given by the exponent. If the + * exponent is 0, the value 1 is returned. + */ + public Rational pow(int exponent) { + if (exponent == 0) + return new Rational(1, 1); - /** Power to an integer. - * @param exponent the exponent. - * @return this value raised to the power given by the exponent. - * If the exponent is 0, the value 1 is returned. - * @since 2009-05-18 - */ - public Rational pow(BigInteger exponent) throws NumberFormatException - { - /* test for overflow */ - if ( exponent.compareTo(MAX_INT) == 1 ) - throw new NumberFormatException("Exponent "+exponent.toString()+" too large.") ; - if ( exponent.compareTo(MIN_INT) == -1 ) - throw new NumberFormatException("Exponent "+exponent.toString()+" too small.") ; + BigInteger num = a.pow(Math.abs(exponent)); + BigInteger deno = b.pow(Math.abs(exponent)); + if (exponent > 0) + return (new Rational(num, deno)); + else + return (new Rational(deno, num)); + } /* Rational.pow */ - /* promote to the simpler interface above */ - return pow( exponent.intValue() ) ; - } /* Rational.pow */ + /** + * Power to an integer. + * + * @param exponent + * the exponent. + * @return this value raised to the power given by the exponent. If the + * exponent is 0, the value 1 is returned. + * @throws Errore + * @since 2009-05-18 + */ + public Rational pow(BigInteger exponent) throws Errore { + /* test for overflow */ + if (exponent.compareTo(MAX_INT) == 1) + throw new Errore(Errori.NUMBER_TOO_LARGE); + if (exponent.compareTo(MIN_INT) == -1) + throw new Errore(Errori.NUMBER_TOO_SMALL); - /** r-th root. - * @param r the inverse of the exponent. - * 2 for the square root, 3 for the third root etc - * @return this value raised to the inverse power given by the root argument, this^(1/r). - * @since 2009-05-18 - */ - public Rational root(BigInteger r) throws NumberFormatException - { - /* test for overflow */ - if ( r.compareTo(MAX_INT) == 1 ) - throw new NumberFormatException("Root "+r.toString()+" too large.") ; - if ( r.compareTo(MIN_INT) == -1 ) - throw new NumberFormatException("Root "+r.toString()+" too small.") ; + /* promote to the simpler interface above */ + return pow(exponent.intValue()); + } /* Rational.pow */ - int rthroot = r.intValue() ; - /* cannot pull root of a negative value with even-valued root */ - if ( compareTo(ZERO) == -1 && (rthroot % 2) ==0 ) - throw new NumberFormatException("Negative basis "+ toString()+" with odd root "+r.toString()) ; + /** + * r-th root. + * + * @param r + * the inverse of the exponent. 2 for the square root, 3 for the + * third root etc + * @return this value raised to the inverse power given by the root + * argument, this^(1/r). + * @throws Errore + * @since 2009-05-18 + */ + public Rational root(BigInteger r) throws Errore { + /* test for overflow */ + if (r.compareTo(MAX_INT) == 1) + throw new Errore(Errori.NUMBER_TOO_LARGE); + if (r.compareTo(MIN_INT) == -1) + throw new Errore(Errori.NUMBER_TOO_SMALL); - /* extract a sign such that we calculate |n|^(1/r), still r carrying any sign - */ - final boolean flipsign = ( compareTo(ZERO) == -1 && (rthroot % 2) != 0) ? true : false ; + int rthroot = r.intValue(); + /* cannot pull root of a negative value with even-valued root */ + if (compareTo(ZERO) == -1 && (rthroot % 2) == 0) + throw new Errore(Errori.NEGATIVE_PARAMETER); - /* delegate the main work to ifactor#root() - */ - Ifactor num = new Ifactor(a.abs()) ; - Ifactor deno = new Ifactor(b) ; - final Rational resul = num.root(rthroot).divide( deno.root(rthroot) ) ; - if ( flipsign) - return resul.negate() ; - else - return resul ; - } /* Rational.root */ + /* + * extract a sign such that we calculate |n|^(1/r), still r carrying any + * sign + */ + final boolean flipsign = (compareTo(ZERO) == -1 && (rthroot % 2) != 0) ? true : false; - /** Raise to a rational power. - * @param exponent The exponent. - * @return This value raised to the power given by the exponent. - * If the exponent is 0, the value 1 is returned. - * @since 2009-05-18 - */ - public Rational pow(Rational exponent) throws NumberFormatException - { - if ( exponent.a.compareTo(BigInteger.ZERO) == 0 ) - return new Rational(1,1) ; + /* + * delegate the main work to ifactor#root() + */ + Ifactor num = new Ifactor(a.abs()); + Ifactor deno = new Ifactor(b); + final Rational resul = num.root(rthroot).divide(deno.root(rthroot)); + if (flipsign) + return resul.negate(); + else + return resul; + } /* Rational.root */ - /* calculate (a/b)^(exponent.a/exponent.b) as ((a/b)^exponent.a)^(1/exponent.b) - * = tmp^(1/exponent.b) - */ - Rational tmp = pow(exponent.a) ; - return tmp.root(exponent.b) ; - } /* Rational.pow */ + /** + * Raise to a rational power. + * + * @param exponent + * The exponent. + * @return This value raised to the power given by the exponent. If the + * exponent is 0, the value 1 is returned. + * @throws Errore + * @since 2009-05-18 + */ + public Rational pow(Rational exponent) throws Errore { + if (exponent.a.compareTo(BigInteger.ZERO) == 0) + return new Rational(1, 1); - /** Divide by another fraction. - * @param val A second rational number. - * @return The value of this/val - */ - public Rational divide(final Rational val) - { - if( val.compareTo(Rational.ZERO) == 0 ) - throw new ArithmeticException("Dividing "+ toString() + " through zero.") ; - BigInteger num = a.multiply(val.b) ; - BigInteger deno = b.multiply(val.a) ; - /* Reduction to a coprime format is done inside the ctor, - * and not repeated here. - */ - return ( new Rational(num,deno) ) ; - } /* Rational.divide */ + /* + * calculate (a/b)^(exponent.a/exponent.b) as + * ((a/b)^exponent.a)^(1/exponent.b) = tmp^(1/exponent.b) + */ + Rational tmp = pow(exponent.a); + return tmp.root(exponent.b); + } /* Rational.pow */ - /** Divide by an integer. - * @param val a second number. - * @return the value of this/val - */ - public Rational divide(BigInteger val) - { - if( val.compareTo(BigInteger.ZERO) == 0 ) - throw new ArithmeticException("Dividing "+ toString() + " through zero.") ; - Rational val2 = new Rational(val,BigInteger.ONE) ; - return ( divide(val2)) ; - } /* Rational.divide */ + /** + * Divide by another fraction. + * + * @param val + * A second rational number. + * @return The value of this/val + * @throws Errore + */ + public Rational divide(final Rational val) throws Errore { + if (val.compareTo(Rational.ZERO) == 0) + throw new Errore(Errori.DIVISION_BY_ZERO); + BigInteger num = a.multiply(val.b); + BigInteger deno = b.multiply(val.a); + /* + * Reduction to a coprime format is done inside the ctor, and not + * repeated here. + */ + return (new Rational(num, deno)); + } /* Rational.divide */ - /** Divide by an integer. - * @param val A second number. - * @return The value of this/val - */ - public Rational divide(int val) - { - if( val == 0 ) - throw new ArithmeticException("Dividing "+ toString() + " through zero.") ; - Rational val2 = new Rational(val,1) ; - return ( divide(val2)) ; - } /* Rational.divide */ + /** + * Divide by an integer. + * + * @param val + * a second number. + * @return the value of this/val + * @throws Errore + */ + public Rational divide(BigInteger val) throws Errore { + if (val.compareTo(BigInteger.ZERO) == 0) + throw new Errore(Errori.DIVISION_BY_ZERO); + Rational val2 = new Rational(val, BigInteger.ONE); + return (divide(val2)); + } /* Rational.divide */ - /** Add another fraction. - * @param val The number to be added - * @return this+val. - */ - public Rational add(Rational val) - { - BigInteger num = a.multiply(val.b).add(b.multiply(val.a)) ; - BigInteger deno = b.multiply(val.b) ; - return ( new Rational(num,deno) ) ; - } /* Rational.add */ + /** + * Divide by an integer. + * + * @param val + * A second number. + * @return The value of this/val + * @throws Errore + */ + public Rational divide(int val) throws Errore { + if (val == 0) + throw new Errore(Errori.DIVISION_BY_ZERO); + Rational val2 = new Rational(val, 1); + return (divide(val2)); + } /* Rational.divide */ - /** Add another integer. - * @param val The number to be added - * @return this+val. - */ - public Rational add(BigInteger val) - { - Rational val2 = new Rational(val,BigInteger.ONE) ; - return ( add(val2) ) ; - } /* Rational.add */ + /** + * Add another fraction. + * + * @param val + * The number to be added + * @return this+val. + */ + public Rational add(Rational val) { + BigInteger num = a.multiply(val.b).add(b.multiply(val.a)); + BigInteger deno = b.multiply(val.b); + return (new Rational(num, deno)); + } /* Rational.add */ - /** Add another integer. - * @param val The number to be added - * @return this+val. - * @since May 26 2010 - */ - public Rational add(int val) - { - BigInteger val2 = a.add(b.multiply(new BigInteger(""+val))) ; - return new Rational(val2,b) ; - } /* Rational.add */ + /** + * Add another integer. + * + * @param val + * The number to be added + * @return this+val. + */ + public Rational add(BigInteger val) { + Rational val2 = new Rational(val, BigInteger.ONE); + return (add(val2)); + } /* Rational.add */ - /** Compute the negative. - * @return -this. - */ - public Rational negate() - { - return ( new Rational(a.negate(),b) ) ; - } /* Rational.negate */ + /** + * Add another integer. + * + * @param val + * The number to be added + * @return this+val. + * @since May 26 2010 + */ + public Rational add(int val) { + BigInteger val2 = a.add(b.multiply(new BigInteger("" + val))); + return new Rational(val2, b); + } /* Rational.add */ - /** Subtract another fraction. - * @param val the number to be subtracted from this - * @return this - val. - */ - public Rational subtract(Rational val) - { - Rational val2 = val.negate() ; - return ( add(val2) ) ; - } /* Rational.subtract */ + /** + * Compute the negative. + * + * @return -this. + */ + public Rational negate() { + return (new Rational(a.negate(), b)); + } /* Rational.negate */ - /** Subtract an integer. - * @param val the number to be subtracted from this - * @return this - val. - */ - public Rational subtract(BigInteger val) - { - Rational val2 = new Rational(val,BigInteger.ONE) ; - return ( subtract(val2) ) ; - } /* Rational.subtract */ + /** + * Subtract another fraction. + * + * @param val + * the number to be subtracted from this + * @return this - val. + */ + public Rational subtract(Rational val) { + Rational val2 = val.negate(); + return (add(val2)); + } /* Rational.subtract */ - /** Subtract an integer. - * @param val the number to be subtracted from this - * @return this - val. - */ - public Rational subtract(int val) - { - Rational val2 = new Rational(val,1) ; - return ( subtract(val2) ) ; - } /* Rational.subtract */ + /** + * Subtract an integer. + * + * @param val + * the number to be subtracted from this + * @return this - val. + */ + public Rational subtract(BigInteger val) { + Rational val2 = new Rational(val, BigInteger.ONE); + return (subtract(val2)); + } /* Rational.subtract */ - /** binomial (n choose m). - * @param n the numerator. Equals the size of the set to choose from. - * @param m the denominator. Equals the number of elements to select. - * @return the binomial coefficient. - * @since 2006-06-27 - * @author Richard J. Mathar - */ - public static Rational binomial(Rational n, BigInteger m) - { - if ( m.compareTo(BigInteger.ZERO) == 0 ) - return Rational.ONE ; - Rational bin = n ; - for(BigInteger i=new BigInteger("2") ; i.compareTo(m) != 1 ; i = i.add(BigInteger.ONE) ) - { - bin = bin.multiply(n.subtract(i.subtract(BigInteger.ONE))).divide(i) ; - } - return bin ; - } /* Rational.binomial */ + /** + * Subtract an integer. + * + * @param val + * the number to be subtracted from this + * @return this - val. + */ + public Rational subtract(int val) { + Rational val2 = new Rational(val, 1); + return (subtract(val2)); + } /* Rational.subtract */ - /** binomial (n choose m). - * @param n the numerator. Equals the size of the set to choose from. - * @param m the denominator. Equals the number of elements to select. - * @return the binomial coefficient. - * @since 2009-05-19 - * @author Richard J. Mathar - */ - public static Rational binomial(Rational n, int m) - { - if ( m == 0 ) - return Rational.ONE ; - Rational bin = n ; - for( int i=2 ; i <= m ; i++ ) - { - bin = bin.multiply(n.subtract(i-1)).divide(i) ; - } - return bin ; - } /* Rational.binomial */ + /** + * binomial (n choose m). + * + * @param n + * the numerator. Equals the size of the set to choose from. + * @param m + * the denominator. Equals the number of elements to select. + * @return the binomial coefficient. + * @since 2006-06-27 + * @author Richard J. Mathar + * @throws Errore + */ + public static Rational binomial(Rational n, BigInteger m) throws Errore { + if (m.compareTo(BigInteger.ZERO) == 0) + return Rational.ONE; + Rational bin = n; + for (BigInteger i = new BigInteger("2"); i.compareTo(m) != 1; i = i.add(BigInteger.ONE)) { + bin = bin.multiply(n.subtract(i.subtract(BigInteger.ONE))).divide(i); + } + return bin; + } /* Rational.binomial */ - /** Hankel's symbol (n,k) - * @param n the first parameter. - * @param k the second parameter, greater or equal to 0. - * @return Gamma(n+k+1/2)/k!/GAMMA(n-k+1/2) - * @since 2010-07-18 - * @author Richard J. Mathar - */ - public static Rational hankelSymb(Rational n, int k) - { - if ( k == 0 ) - return Rational.ONE ; - else if ( k < 0) - throw new ArithmeticException("Negative parameter "+k) ; - Rational nkhalf = n.subtract(k).add(Rational.HALF) ; - nkhalf = nkhalf.Pochhammer(2*k) ; - Factorial f = new Factorial() ; - return nkhalf.divide(f.at(k)) ; - } /* Rational.binomial */ + /** + * binomial (n choose m). + * + * @param n + * the numerator. Equals the size of the set to choose from. + * @param m + * the denominator. Equals the number of elements to select. + * @return the binomial coefficient. + * @since 2009-05-19 + * @author Richard J. Mathar + * @throws Errore + */ + public static Rational binomial(Rational n, int m) throws Errore { + if (m == 0) + return Rational.ONE; + Rational bin = n; + for (int i = 2; i <= m; i++) { + bin = bin.multiply(n.subtract(i - 1)).divide(i); + } + return bin; + } /* Rational.binomial */ - /** Get the numerator. - * @return The numerator of the reduced fraction. - */ - public BigInteger numer() - { - return a ; - } + /** + * Hankel's symbol (n,k) + * + * @param n + * the first parameter. + * @param k + * the second parameter, greater or equal to 0. + * @return Gamma(n+k+1/2)/k!/GAMMA(n-k+1/2) + * @since 2010-07-18 + * @author Richard J. Mathar + * @throws Errore + */ + public static Rational hankelSymb(Rational n, int k) throws Errore { + if (k == 0) + return Rational.ONE; + else if (k < 0) + throw new Errore(Errori.NEGATIVE_PARAMETER); + Rational nkhalf = n.subtract(k).add(Rational.HALF); + nkhalf = nkhalf.Pochhammer(2 * k); + Factorial f = new Factorial(); + return nkhalf.divide(f.at(k)); + } /* Rational.binomial */ - /** Get the denominator. - * @return The denominator of the reduced fraction. - */ - public BigInteger denom() - { - return b ; - } + /** + * Get the numerator. + * + * @return The numerator of the reduced fraction. + */ + public BigInteger numer() { + return a; + } - /** Absolute value. - * @return The absolute (non-negative) value of this. - */ - public Rational abs() - { - return( new Rational(a.abs(),b.abs())) ; - } + /** + * Get the denominator. + * + * @return The denominator of the reduced fraction. + */ + public BigInteger denom() { + return b; + } - /** floor(): the nearest integer not greater than this. - * @return The integer rounded towards negative infinity. - */ - public BigInteger floor() - { - /* is already integer: return the numerator - */ - if ( b.compareTo(BigInteger.ONE) == 0 ) - return a; - else if ( a.compareTo(BigInteger.ZERO) > 0 ) - return a.divide(b); - else - return a.divide(b).subtract(BigInteger.ONE) ; - } /* Rational.floor */ + /** + * Absolute value. + * + * @return The absolute (non-negative) value of this. + */ + public Rational abs() { + return (new Rational(a.abs(), b.abs())); + } - /** ceil(): the nearest integer not smaller than this. - * @return The integer rounded towards positive infinity. - * @since 2010-05-26 - */ - public BigInteger ceil() - { - /* is already integer: return the numerator - */ - if ( b.compareTo(BigInteger.ONE) == 0 ) - return a; - else if ( a.compareTo(BigInteger.ZERO) > 0 ) - return a.divide(b).add(BigInteger.ONE) ; - else - return a.divide(b) ; - } /* Rational.ceil */ + /** + * floor(): the nearest integer not greater than this. + * + * @return The integer rounded towards negative infinity. + */ + public BigInteger floor() { + /* + * is already integer: return the numerator + */ + if (b.compareTo(BigInteger.ONE) == 0) + return a; + else if (a.compareTo(BigInteger.ZERO) > 0) + return a.divide(b); + else + return a.divide(b).subtract(BigInteger.ONE); + } /* Rational.floor */ - /** Remove the fractional part. - * @return The integer rounded towards zero. - */ - public BigInteger trunc() - { - /* is already integer: return the numerator - */ - if ( b.compareTo(BigInteger.ONE) == 0 ) - return a; - else - return a.divide(b); - } /* Rational.trunc */ + /** + * ceil(): the nearest integer not smaller than this. + * + * @return The integer rounded towards positive infinity. + * @since 2010-05-26 + */ + public BigInteger ceil() { + /* + * is already integer: return the numerator + */ + if (b.compareTo(BigInteger.ONE) == 0) + return a; + else if (a.compareTo(BigInteger.ZERO) > 0) + return a.divide(b).add(BigInteger.ONE); + else + return a.divide(b); + } /* Rational.ceil */ - /** Compares the value of this with another constant. - * @param val the other constant to compare with - * @return -1, 0 or 1 if this number is numerically less than, equal to, - * or greater than val. - */ - public int compareTo(final Rational val) - { - /* Since we have always kept the denominators positive, - * simple cross-multiplying works without changing the sign. - */ - final BigInteger left = a.multiply(val.b) ; - final BigInteger right = val.a.multiply(b) ; - return left.compareTo(right) ; - } /* Rational.compareTo */ + /** + * Remove the fractional part. + * + * @return The integer rounded towards zero. + */ + public BigInteger trunc() { + /* + * is already integer: return the numerator + */ + if (b.compareTo(BigInteger.ONE) == 0) + return a; + else + return a.divide(b); + } /* Rational.trunc */ - /** Compares the value of this with another constant. - * @param val the other constant to compare with - * @return -1, 0 or 1 if this number is numerically less than, equal to, - * or greater than val. - */ - public int compareTo(final BigInteger val) - { - final Rational val2 = new Rational(val,BigInteger.ONE) ; - return ( compareTo(val2) ) ; - } /* Rational.compareTo */ + /** + * Compares the value of this with another constant. + * + * @param val + * the other constant to compare with + * @return -1, 0 or 1 if this number is numerically less than, equal to, or + * greater than val. + */ + public int compareTo(final Rational val) { + /* + * Since we have always kept the denominators positive, simple + * cross-multiplying works without changing the sign. + */ + final BigInteger left = a.multiply(val.b); + final BigInteger right = val.a.multiply(b); + return left.compareTo(right); + } /* Rational.compareTo */ - /** Return a string in the format number/denom. - * If the denominator equals 1, print just the numerator without a slash. - * @return the human-readable version in base 10 - */ - public String toString() - { - if ( b.compareTo(BigInteger.ONE) != 0) - return( a.toString()+"/"+b.toString() ) ; - else - return a.toString() ; - } /* Rational.toString */ + /** + * Compares the value of this with another constant. + * + * @param val + * the other constant to compare with + * @return -1, 0 or 1 if this number is numerically less than, equal to, or + * greater than val. + */ + public int compareTo(final BigInteger val) { + final Rational val2 = new Rational(val, BigInteger.ONE); + return (compareTo(val2)); + } /* Rational.compareTo */ - /** Return a double value representation. - * @return The value with double precision. - * @since 2008-10-26 - */ - public double doubleValue() - { - /* To meet the risk of individual overflows of the exponents of - * a separate invocation a.doubleValue() or b.doubleValue(), we divide first - * in a BigDecimal environment and convert the result. - */ - BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128) ; - return adivb.doubleValue() ; - } /* Rational.doubleValue */ + /** + * Return a string in the format number/denom. If the denominator equals 1, + * print just the numerator without a slash. + * + * @return the human-readable version in base 10 + */ + public String toString() { + if (b.compareTo(BigInteger.ONE) != 0) + return (a.toString() + "/" + b.toString()); + else + return a.toString(); + } /* Rational.toString */ - /** Return a float value representation. - * @return The value with single precision. - * @since 2009-08-06 - */ - public float floatValue() - { - BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128) ; - return adivb.floatValue() ; - } /* Rational.floatValue */ + /** + * Return a double value representation. + * + * @return The value with double precision. + * @since 2008-10-26 + */ + public double doubleValue() { + /* + * To meet the risk of individual overflows of the exponents of a + * separate invocation a.doubleValue() or b.doubleValue(), we divide + * first in a BigDecimal environment and convert the result. + */ + BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128); + return adivb.doubleValue(); + } /* Rational.doubleValue */ - /** Return a representation as BigDecimal. - * @param mc the mathematical context which determines precision, rounding mode etc - * @return A representation as a BigDecimal floating point number. - * @since 2008-10-26 - */ - public BigDecimal BigDecimalValue(MathContext mc) - { - /* numerator and denominator individually rephrased - */ - BigDecimal n = new BigDecimal(a) ; - BigDecimal d = new BigDecimal(b) ; - /* the problem with n.divide(d,mc) is that the apparent precision might be - * smaller than what is set by mc if the value has a precise truncated representation. - * 1/4 will appear as 0.25, independent of mc - */ - return BigDecimalMath.scalePrec(n.divide(d,mc),mc) ; - } /* Rational.BigDecimalValue */ + /** + * Return a float value representation. + * + * @return The value with single precision. + * @since 2009-08-06 + */ + public float floatValue() { + BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128); + return adivb.floatValue(); + } /* Rational.floatValue */ - /** Return a string in floating point format. - * @param digits The precision (number of digits) - * @return The human-readable version in base 10. - * @since 2008-10-25 - */ - public String toFString(int digits) - { - if ( b.compareTo(BigInteger.ONE) != 0) - { - MathContext mc = new MathContext(digits,RoundingMode.DOWN) ; - BigDecimal f = (new BigDecimal(a)).divide(new BigDecimal(b),mc) ; - return( f.toString() ) ; - } - else - return a.toString() ; - } /* Rational.toFString */ + /** + * Return a representation as BigDecimal. + * + * @param mc + * the mathematical context which determines precision, rounding + * mode etc + * @return A representation as a BigDecimal floating point number. + * @since 2008-10-26 + */ + public BigDecimal BigDecimalValue(MathContext mc) { + /* + * numerator and denominator individually rephrased + */ + BigDecimal n = new BigDecimal(a); + BigDecimal d = new BigDecimal(b); + /* + * the problem with n.divide(d,mc) is that the apparent precision might + * be smaller than what is set by mc if the value has a precise + * truncated representation. 1/4 will appear as 0.25, independent of mc + */ + return BigDecimalMath.scalePrec(n.divide(d, mc), mc); + } /* Rational.BigDecimalValue */ - /** Compares the value of this with another constant. - * @param val The other constant to compare with - * @return The arithmetic maximum of this and val. - * @since 2008-10-19 - */ - public Rational max(final Rational val) - { - if ( compareTo(val) > 0 ) - return this; - else - return val; - } /* Rational.max */ + /** + * Return a string in floating point format. + * + * @param digits + * The precision (number of digits) + * @return The human-readable version in base 10. + * @since 2008-10-25 + */ + public String toFString(int digits) { + if (b.compareTo(BigInteger.ONE) != 0) { + MathContext mc = new MathContext(digits, RoundingMode.DOWN); + BigDecimal f = (new BigDecimal(a)).divide(new BigDecimal(b), mc); + return (f.toString()); + } else + return a.toString(); + } /* Rational.toFString */ - /** Compares the value of this with another constant. - * @param val The other constant to compare with - * @return The arithmetic minimum of this and val. - * @since 2008-10-19 - */ - public Rational min(final Rational val) - { - if ( compareTo(val) < 0 ) - return this; - else - return val; - } /* Rational.min */ + /** + * Compares the value of this with another constant. + * + * @param val + * The other constant to compare with + * @return The arithmetic maximum of this and val. + * @since 2008-10-19 + */ + public Rational max(final Rational val) { + if (compareTo(val) > 0) + return this; + else + return val; + } /* Rational.max */ - /** Compute Pochhammer's symbol (this)_n. - * @param n The number of product terms in the evaluation. - * @return Gamma(this+n)/Gamma(this) = this*(this+1)*...*(this+n-1). - * @since 2008-10-25 - */ - public Rational Pochhammer(final BigInteger n) - { - if ( n.compareTo(BigInteger.ZERO) < 0 ) - return null; - else if ( n.compareTo(BigInteger.ZERO) == 0 ) - return Rational.ONE ; - else - { - /* initialize results with the current value - */ - Rational res = new Rational(a,b) ; - BigInteger i = BigInteger.ONE ; - for( ; i.compareTo(n) < 0 ; i=i.add(BigInteger.ONE) ) - res = res.multiply( add(i) ) ; - return res; - } - } /* Rational.pochhammer */ + /** + * Compares the value of this with another constant. + * + * @param val + * The other constant to compare with + * @return The arithmetic minimum of this and val. + * @since 2008-10-19 + */ + public Rational min(final Rational val) { + if (compareTo(val) < 0) + return this; + else + return val; + } /* Rational.min */ - /** Compute pochhammer's symbol (this)_n. - * @param n The number of product terms in the evaluation. - * @return Gamma(this+n)/GAMMA(this). - * @since 2008-11-13 - */ - public Rational Pochhammer(int n) - { - return Pochhammer(new BigInteger(""+n)) ; - } /* Rational.pochhammer */ + /** + * Compute Pochhammer's symbol (this)_n. + * + * @param n + * The number of product terms in the evaluation. + * @return Gamma(this+n)/Gamma(this) = this*(this+1)*...*(this+n-1). + * @since 2008-10-25 + */ + public Rational Pochhammer(final BigInteger n) { + if (n.compareTo(BigInteger.ZERO) < 0) + return null; + else if (n.compareTo(BigInteger.ZERO) == 0) + return Rational.ONE; + else { + /* + * initialize results with the current value + */ + Rational res = new Rational(a, b); + BigInteger i = BigInteger.ONE; + for (; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) + res = res.multiply(add(i)); + return res; + } + } /* Rational.pochhammer */ - /** True if the value is integer. - * Equivalent to the indication whether a conversion to an integer - * can be exact. - * @since 2010-05-26 - */ - public boolean isBigInteger() - { - return ( b.abs().compareTo(BigInteger.ONE) == 0 ) ; - } /* Rational.isBigInteger */ + /** + * Compute pochhammer's symbol (this)_n. + * + * @param n + * The number of product terms in the evaluation. + * @return Gamma(this+n)/GAMMA(this). + * @since 2008-11-13 + */ + public Rational Pochhammer(int n) { + return Pochhammer(new BigInteger("" + n)); + } /* Rational.pochhammer */ - /** True if the value is integer and in the range of the standard integer. - * Equivalent to the indication whether a conversion to an integer - * can be exact. - * @since 2010-05-26 - */ - public boolean isInteger() - { - if ( ! isBigInteger() ) - return false; - return ( a.compareTo(MAX_INT) <= 0 && a.compareTo(MIN_INT) >= 0 ) ; - } /* Rational.isInteger */ + /** + * True if the value is integer. Equivalent to the indication whether a + * conversion to an integer can be exact. + * + * @since 2010-05-26 + */ + public boolean isBigInteger() { + return (b.abs().compareTo(BigInteger.ONE) == 0); + } /* Rational.isBigInteger */ + /** + * True if the value is integer and in the range of the standard integer. + * Equivalent to the indication whether a conversion to an integer can be + * exact. + * + * @since 2010-05-26 + */ + public boolean isInteger() { + if (!isBigInteger()) + return false; + return (a.compareTo(MAX_INT) <= 0 && a.compareTo(MIN_INT) >= 0); + } /* Rational.isInteger */ - /** Conversion to an integer value, if this can be done exactly. - * @since 2011-02-13 - */ - int intValue() - { - if ( ! isInteger() ) - throw new NumberFormatException("cannot convert "+toString()+" to integer.") ; - return a.intValue() ; - } + /** + * Conversion to an integer value, if this can be done exactly. + * @throws Errore + * + * @since 2011-02-13 + */ + int intValue() throws Errore { + if (!isInteger()) + throw new Errore(Errori.CONVERSION_ERROR); + return a.intValue(); + } - /** Conversion to a BigInteger value, if this can be done exactly. - * @since 2012-03-02 - */ - BigInteger BigIntegerValue() - { - if ( ! isBigInteger() ) - throw new NumberFormatException("cannot convert "+toString()+" to BigInteger.") ; - return a ; - } + /** + * Conversion to a BigInteger value, if this can be done exactly. + * @throws Errore + * + * @since 2012-03-02 + */ + BigInteger BigIntegerValue() throws Errore { + if (!isBigInteger()) + throw new Errore(Errori.CONVERSION_ERROR); + return a; + } - /** True if the value is a fraction of two integers in the range of the standard integer. - * @since 2010-05-26 - */ - public boolean isIntegerFrac() - { - return ( a.compareTo(MAX_INT) <= 0 && a.compareTo(MIN_INT) >= 0 - && b.compareTo(MAX_INT) <= 0 && b.compareTo(MIN_INT) >= 0 ) ; - } /* Rational.isIntegerFrac */ + /** + * True if the value is a fraction of two integers in the range of the + * standard integer. + * + * @since 2010-05-26 + */ + public boolean isIntegerFrac() { + return (a.compareTo(MAX_INT) <= 0 && a.compareTo(MIN_INT) >= 0 && b.compareTo(MAX_INT) <= 0 + && b.compareTo(MIN_INT) >= 0); + } /* Rational.isIntegerFrac */ - /** The sign: 1 if the number is >0, 0 if ==0, -1 if <0 - * @return the signum of the value. - * @since 2010-05-26 - */ - public int signum() - { - return ( b.signum() * a.signum() ) ; - } /* Rational.signum */ + /** + * The sign: 1 if the number is >0, 0 if ==0, -1 if <0 + * + * @return the signum of the value. + * @since 2010-05-26 + */ + public int signum() { + return (b.signum() * a.signum()); + } /* Rational.signum */ - /** Common lcm of the denominators of a set of rational values. - * @param vals The list/set of the rational values. - * @return LCM(denom of first, denom of second, ..,denom of last) - * @since 2012-03-02 - */ - static public BigInteger lcmDenom(final Rational[] vals) - { - BigInteger l = BigInteger.ONE ; - for(int v= 0 ; v < vals.length ; v++) - l = BigIntegerMath.lcm(l,vals[v].b) ; - return l ; - } /* Rational.lcmDenom */ + /** + * Common lcm of the denominators of a set of rational values. + * + * @param vals + * The list/set of the rational values. + * @return LCM(denom of first, denom of second, ..,denom of last) + * @since 2012-03-02 + */ + static public BigInteger lcmDenom(final Rational[] vals) { + BigInteger l = BigInteger.ONE; + for (int v = 0; v < vals.length; v++) + l = BigIntegerMath.lcm(l, vals[v].b); + return l; + } /* Rational.lcmDenom */ - /** Normalize to coprime numerator and denominator. - * Also copy a negative sign of the denominator to the numerator. - * @since 2008-10-19 - */ - protected void normalize() - { - /* compute greatest common divisor of numerator and denominator - */ - final BigInteger g = a.gcd(b) ; - if ( g.compareTo(BigInteger.ONE) > 0 ) - { - a = a.divide(g) ; - b = b.divide(g); - } - if ( b.compareTo(BigInteger.ZERO) == -1 ) - { - a = a.negate() ; - b = b.negate() ; - } - } /* Rational.normalize */ + /** + * Normalize to coprime numerator and denominator. Also copy a negative sign + * of the denominator to the numerator. + * + * @since 2008-10-19 + */ + protected void normalize() { + /* + * compute greatest common divisor of numerator and denominator + */ + final BigInteger g = a.gcd(b); + if (g.compareTo(BigInteger.ONE) > 0) { + a = a.divide(g); + b = b.divide(g); + } + if (b.compareTo(BigInteger.ZERO) == -1) { + a = a.negate(); + b = b.negate(); + } + } /* Rational.normalize */ } /* Rational */ - diff --git a/src/org/nevec/rjm/Wigner3j.java b/src/org/nevec/rjm/Wigner3j.java index c604cd2d..3c55a874 100644 --- a/src/org/nevec/rjm/Wigner3j.java +++ b/src/org/nevec/rjm/Wigner3j.java @@ -3,6 +3,8 @@ package org.nevec.rjm; import java.math.BigInteger; import java.util.Scanner; +import org.warpgate.pi.calculator.Errore; + /** * Exact representations of Wigner 3jm and 3nj values of half-integer arguments. * @@ -30,8 +32,9 @@ public class Wigner3j { * * @since 2011-02-15 * @author Richard J. Mathar + * @throws Errore */ - static public void main(String args[]) { + static public void main(String args[]) throws Errore { if (args[0].compareTo("6j") == 0) { try { String m1 = "6"; @@ -102,8 +105,9 @@ public class Wigner3j { * inequalities is violated or some parameters are out of range. * @since 2011-02-13 * @author Richard J. Mathar + * @throws Errore */ - static public BigSurd wigner3jm(int j1, int j2, int j3, int m1, int m2, int m3) { + static public BigSurd wigner3jm(int j1, int j2, int j3, int m1, int m2, int m3) throws Errore { Rational J1 = new Rational(j1, 2); Rational J2 = new Rational(j2, 2); Rational J3 = new Rational(j3, 2); @@ -136,8 +140,9 @@ public class Wigner3j { * @since 2011-02-13 * @since 2012-02-15 Upgraded return value to BigSurdVec * @author Richard J. Mathar + * @throws Errore */ - static public BigSurdVec wigner3j(String m1, String t1, String t2, String j) { + static public BigSurdVec wigner3j(String m1, String t1, String t2, String j) throws Errore { /* * The first number in the line "m" is the number of angular momenta. * The rest of the line is ignored. @@ -265,8 +270,9 @@ public class Wigner3j { * @since 2011-02-13 * @since 2012-02-15 Upgraded to return BigSurdVec * @author Richard J. Mathar + * @throws Errore */ - static private BigSurdVec wigner3j(final int[] tvec, final Rational[] J, final Rational[] M, final int[] triadidx) { + static private BigSurdVec wigner3j(final int[] tvec, final Rational[] J, final Rational[] M, final int[] triadidx) throws Errore { /* * The result of the computation. The sum over all m-combinations of the * triads. @@ -473,8 +479,9 @@ public class Wigner3j { * inequalities is violated or some parameters are out of range. * @since 2011-02-13 * @author Richard J. Mathar + * @throws Errore */ - static protected BigSurd wigner3jm(Rational j1, Rational j2, Rational j3, Rational m1, Rational m2, Rational m3) { + static protected BigSurd wigner3jm(Rational j1, Rational j2, Rational j3, Rational m1, Rational m2, Rational m3) throws Errore { /* * Check that m1+m2+m3 = 0 */ diff --git a/src/org/nevec/rjm/Wigner3jGUI.java b/src/org/nevec/rjm/Wigner3jGUI.java index b7008ee1..6c9e245d 100644 --- a/src/org/nevec/rjm/Wigner3jGUI.java +++ b/src/org/nevec/rjm/Wigner3jGUI.java @@ -16,6 +16,8 @@ import javax.swing.JList; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import org.warpgate.pi.calculator.Errore; + /** * An interactive interface to the Wigner3j class. The GUI allows to preselect * one of the symbols if the number of j-terms is small (6j up to 15j), or to @@ -133,9 +135,10 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener { } /* init */ /** + * @throws Errore * @since 2010-08-27 */ - public void compute() { + public void compute() throws Errore { String tr = inpGtria.getText(); String[] trias = new String[4]; @@ -206,7 +209,12 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener { */ if (lin == "compute") { outG.setText(""); - compute(); + try { + compute(); + } catch (Errore e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } } } /* actionPerformed */ diff --git a/src/org/warpgate/pi/calculator/Calculator.java b/src/org/warpgate/pi/calculator/Calculator.java index 6154ad90..eaf5bb16 100644 --- a/src/org/warpgate/pi/calculator/Calculator.java +++ b/src/org/warpgate/pi/calculator/Calculator.java @@ -1,36 +1,36 @@ -package org.warpgate.pi.calculator; - -import org.nevec.rjm.BigSurdVec; - -public class Calculator { - - public Calculator(boolean b) { - Utils.debugOn = b; - } - - public Termine calcolarisultato(String string) throws Errore { - System.out.println("INPUT: " + string); - Parentesi espressione = new Parentesi(string, ""); - return espressione.calcola(); - } - - public RisultatoEquazione calcolaequazione(String string) throws Errore { - if (string.split("=").length == 0) { - return new RisultatoEquazione(new Termine("0"), true); - } - if (string.split("=").length <= 2) { - if (string.split("=").length == 1) { - string = string + "=0"; - } - Termine res1 = calcolarisultato(string.split("=")[0]); - Termine res2 = calcolarisultato(string.split("=")[1]); - Termine res = res1.add(res2.multiply(new Termine("-1"))); - if (res.calcola().getTerm().toString().equals("0")) { - return new RisultatoEquazione(res.calcola(), true); - } - return new RisultatoEquazione(res.calcola(), false); - } - return new RisultatoEquazione(null, false); - } - -} +package org.warpgate.pi.calculator; + +import org.nevec.rjm.NumeroAvanzatoVec; + +public class Calculator { + + public Calculator(boolean b) { + Utils.debugOn = b; + } + + public Termine calcolarisultato(String string) throws Errore { + System.out.println("INPUT: " + string); + Parentesi espressione = new Parentesi(string); + return espressione.calcola(); + } + + public RisultatoEquazione calcolaequazione(String string) throws Errore { + if (string.split("=").length == 0) { + return new RisultatoEquazione(new Termine("0"), true); + } + if (string.split("=").length <= 2) { + if (string.split("=").length == 1) { + string = string + "=0"; + } + Termine res1 = calcolarisultato(string.split("=")[0]); + Termine res2 = calcolarisultato(string.split("=")[1]); + Termine res = res1.add(res2.multiply(new Termine("-1"))); + if (res.calcola().getTerm().toString().equals("0")) { + return new RisultatoEquazione(res.calcola(), true); + } + return new RisultatoEquazione(res.calcola(), false); + } + return new RisultatoEquazione(null, false); + } + +} diff --git a/src/org/warpgate/pi/calculator/Divisione.java b/src/org/warpgate/pi/calculator/Divisione.java index cede107c..a161e841 100644 --- a/src/org/warpgate/pi/calculator/Divisione.java +++ b/src/org/warpgate/pi/calculator/Divisione.java @@ -1,23 +1,169 @@ -package org.warpgate.pi.calculator; - -import org.nevec.rjm.BigSurdVec; - -public class Divisione extends FunzioneDueValori { - - public Divisione(Funzione value1, Funzione value2) { - super(value1, value2); - } - - @Override - public String simbolo() { - return Simboli.DIVISION; - } - - @Override - public Termine calcola() throws Errore { - if (getVariable2().calcola().getTerm().compareTo(BigSurdVec.ZERO) == 0) { - throw new Errore(Errori.DIVISION_BY_ZERO); - } - return getVariable1().calcola().divide(getVariable2().calcola()); - } +package org.warpgate.pi.calculator; + +import java.awt.Color; +import java.awt.Graphics; + +import org.nevec.rjm.NumeroAvanzatoVec; +import org.nevec.rjm.Rational; +import org.warp.engine.Display; + +public class Divisione extends FunzioneDueValori { + + public Divisione(Funzione value1, Funzione value2) { + super(value1, value2); + } + + @Override + public String simbolo() { + return Simboli.DIVISION; + } + + @Override + public Termine calcola() throws Errore { + if (variable2 == null || variable1 == null) { + return new Termine("0"); + } + if (variable2.calcola().getTerm().compareTo(NumeroAvanzatoVec.ZERO) == 0) { + throw new Errore(Errori.DIVISION_BY_ZERO); + } + return variable1.calcola().divide(variable2.calcola()); + } + + public boolean hasMinus() { + String numerator = variable1.toString(); + if (numerator.startsWith("-")) { + return true; + } + return false; + } + + public void draw(int x, int y, Display g, boolean small, boolean drawMinus) { + boolean beforedrawminus = this.drawMinus; + this.drawMinus = drawMinus; + draw(x, y, g, small); + this.drawMinus = beforedrawminus; + } + + private boolean drawMinus = true; + + @Override + public void draw(int x, int y, Display g, boolean small) { + Object var1 = variable1; + Object var2 = variable2; + small = true; + boolean minus = false; + int minusw = 0; + int minush = 0; + String numerator = ((Funzione)var1).toString(); + if (numerator.startsWith("-") && ((Funzione)var1) instanceof Termine && ((Termine)var1).term.isBigInteger(true)) { + minus = true; + numerator = numerator.substring(1); + } + int w1 = 0; + int h1 = 0; + if (minus) { + w1 = Utils.getPlainTextWidth(numerator); + h1 = Utils.getFontHeight(small); + } else { + w1 = ((Funzione)var1).getWidth(); + h1 = ((Funzione)var1).getHeight(small); + } + int w2 = ((Funzione)var2).getWidth(); + int maxw; + if (w1 > w2) { + maxw = 1+w1+1; + } else { + maxw = 1+w2+1; + } + if (minus && drawMinus) { + minusw = Utils.getPlainTextWidth("-")+1; + minush = Utils.getFontHeight(small); + Utils.writeLetter(g, "-", x, y+h1+1+1-(minush/2), small); + Utils.writeLetter(g, numerator, (int)(x+minusw+1+((double)(maxw-w1))/2d), y, small); + } else { + ((Funzione)var1).draw((int)(x+minusw+1+((double)(maxw-w1))/2d), y, g, true); + } + ((Funzione)var2).draw((int)(x+minusw+1+((double)(maxw-w2))/2d), y+h1+1+1+1, g, true); + g.setColor(Color.BLACK); + g.fillRect(x+minusw+1, y+h1+1, maxw, 1); + } + + public int getHeight(boolean small, boolean drawMinus) { + boolean beforedrawminus = this.drawMinus; + this.drawMinus = drawMinus; + int h = getHeight(small); + this.drawMinus = beforedrawminus; + return h; + } + + @Override + public int getHeight(boolean small) { + boolean minus = false; + small = true; + String numerator = variable1.toString(); + if (numerator.startsWith("-") && variable1 instanceof Termine && ((Termine) variable1).term.isBigInteger(true)) { + minus = true; + numerator = numerator.substring(1); + } + int w1 = 0; + int h1 = 0; + if (minus) { + w1 = Utils.getPlainTextWidth(numerator); + h1 = Utils.getFontHeight(small); + } else { + w1 = variable1.getWidth(); + h1 = variable1.getHeight(small); + } + int w2 = variable2.getWidth(); + int h2 = variable2.getHeight(small); + int maxw; + if (w1 > w2) { + maxw = 1+w1+1; + } else { + maxw = 1+w2+1; + } + return h1+3+h2; + } + + @Override + public int getLine(boolean small) { + return variable1.getHeight(true)+1; + } + + public int getWidth(boolean drawMinus) { + boolean beforedrawminus = this.drawMinus; + this.drawMinus = drawMinus; + int w = getWidth(); + this.drawMinus = beforedrawminus; + return w; + } + + @Override + public int getWidth() { + boolean minus = false; + String numerator = variable1.toString(); + if (numerator.startsWith("-") && variable1 instanceof Termine && ((Termine) variable1).term.isBigInteger(true)) { + minus = true; + numerator = numerator.substring(1); + } + int w1 = 0; + int h1 = 0; + if (minus) { + w1 = Utils.getPlainTextWidth(numerator); + } else { + w1 = variable1.getWidth(); + } + int w2 = variable2.getWidth(); + int maxw; + if (w1 > w2) { + maxw = 1+w1+1; + } else { + maxw = 1+w2+1; + } + if (minus && drawMinus) { + return Utils.getPlainTextWidth("-")+1+maxw+1; + } else { + return maxw+2; + } + } } \ No newline at end of file diff --git a/src/org/warpgate/pi/calculator/Errori.java b/src/org/warpgate/pi/calculator/Errori.java index 711c0253..b9697ebf 100644 --- a/src/org/warpgate/pi/calculator/Errori.java +++ b/src/org/warpgate/pi/calculator/Errori.java @@ -1,8 +1,13 @@ -package org.warpgate.pi.calculator; - -public enum Errori { - ERROR, - DIVISION_BY_ZERO, - UNBALANCED_BRACKETS, - NOT_IMPLEMENTED -} +package org.warpgate.pi.calculator; + +public enum Errori { + ERROR, + DIVISION_BY_ZERO, + UNBALANCED_BRACKETS, + NOT_IMPLEMENTED, + NEGATIVE_PARAMETER, + NUMBER_TOO_LARGE, + NUMBER_TOO_SMALL, + CONVERSION_ERROR, + SYNTAX_ERROR +} diff --git a/src/org/warpgate/pi/calculator/Funzione.java b/src/org/warpgate/pi/calculator/Funzione.java index fe6e503c..ed7a09a1 100644 --- a/src/org/warpgate/pi/calculator/Funzione.java +++ b/src/org/warpgate/pi/calculator/Funzione.java @@ -1,6 +1,14 @@ -package org.warpgate.pi.calculator; - -public interface Funzione { - public String simbolo(); - public Termine calcola() throws Errore; -} +package org.warpgate.pi.calculator; + +import org.warp.engine.Display; + +import com.rits.cloning.Cloner; + +public interface Funzione { + public String simbolo(); + public Termine calcola() throws Errore; + public void draw(int x, int y, Display g, boolean small); + public int getWidth(); + public int getHeight(boolean small); + public int getLine(boolean small); +} diff --git a/src/org/warpgate/pi/calculator/FunzioneAnteriore.java b/src/org/warpgate/pi/calculator/FunzioneAnteriore.java new file mode 100644 index 00000000..a8fb90dc --- /dev/null +++ b/src/org/warpgate/pi/calculator/FunzioneAnteriore.java @@ -0,0 +1,66 @@ +package org.warpgate.pi.calculator; + +import org.nevec.rjm.NumeroAvanzatoVec; +import org.warp.engine.Display; + +import com.rits.cloning.Cloner; + +public abstract class FunzioneAnteriore implements Funzione { + public FunzioneAnteriore(Funzione value) { + setVariable(value); + } + protected Funzione variable = new Termine(NumeroAvanzatoVec.ZERO); + public Funzione getVariable() { + return variable; + } + public void setVariable(Funzione value) { + variable = value; + } + @Override + public abstract String simbolo(); + @Override + public abstract Termine calcola() throws Errore; + + + @Override + public void draw(int x, int y, Display g, boolean small) { + int w1 = getVariable().getWidth(); + float h1 = getVariable().getHeight(small); + int wsegno = Utils.getPlainTextWidth(simbolo()); + float hsegno = Utils.getFontHeight(small); + float maxh = getHeight(small); + + Utils.writeLetter(g, simbolo(), x, (int)Math.floor(y+(maxh-hsegno)/2), small); + getVariable().draw(x+wsegno+1, (int)Math.floor(y+(maxh-h1)/2), g, small); + } + + @Override + public int getWidth() { + return Utils.getPlainTextWidth(simbolo())+1+getVariable().getWidth(); + } + + @Override + public int getHeight(boolean small) { + return variable.getHeight(small); + } + + @Override + public int getLine(boolean small) { + return variable.getLine(small); + } + + @Override + public String toString() { + try { + return calcola().toString(); + } catch (Errore e) { + return e.id.toString(); + } + } + + @Override + public FunzioneAnteriore clone() { + Cloner cloner = new Cloner(); + return cloner.deepClone(this); + } +} diff --git a/src/org/warpgate/pi/calculator/FunzioneDueValori.java b/src/org/warpgate/pi/calculator/FunzioneDueValori.java index 0085e8ef..f4355e3e 100644 --- a/src/org/warpgate/pi/calculator/FunzioneDueValori.java +++ b/src/org/warpgate/pi/calculator/FunzioneDueValori.java @@ -1,28 +1,92 @@ -package org.warpgate.pi.calculator; - -import org.nevec.rjm.Rational; - -public abstract class FunzioneDueValori implements Funzione { - public FunzioneDueValori(Funzione value1, Funzione value2) { - setVariable1(value1); - setVariable2(value2); - } - protected Funzione variable1 = new Termine(Rational.ZERO); - public Funzione getVariable1() { - return variable1; - } - public void setVariable1(Funzione value) { - variable1 = value; - } - protected Funzione variable2 = new Termine(Rational.ZERO); - public Funzione getVariable2() { - return variable2; - } - public void setVariable2(Funzione value) { - variable2 = value; - } - @Override - public abstract String simbolo(); - @Override - public abstract Termine calcola() throws Errore; -} +package org.warpgate.pi.calculator; + +import org.nevec.rjm.Rational; +import org.warp.engine.Display; + +import com.rits.cloning.Cloner; + +public abstract class FunzioneDueValori implements Funzione { + public FunzioneDueValori(Funzione value1, Funzione value2) { + setVariable1(value1); + setVariable2(value2); + } + protected Funzione variable1 = new Termine(Rational.ZERO); + public Funzione getVariable1() { + return variable1; + } + public void setVariable1(Funzione value) { + variable1 = value; + } + protected Funzione variable2 = new Termine(Rational.ZERO); + public Funzione getVariable2() { + return variable2; + } + public void setVariable2(Funzione value) { + variable2 = value; + } + @Override + public abstract String simbolo(); + @Override + public abstract Termine calcola() throws Errore; + + + @Override + public void draw(int x, int y, Display g, boolean small) { + int ln = getLine(small); + int dx = 0; + variable1.draw(dx+x, ln-variable1.getLine(small)+y, g, small); + dx+=variable1.getWidth()+1; + if (drawSignum()) { + Utils.writeLetter(g, simbolo(), dx+x, ln-Utils.getFontHeight(small)/2+y, small); + dx+=1; + dx+=Utils.getPlainTextWidth(simbolo()); + } + variable2.draw(dx+x, ln-variable2.getLine(small)+y, g, small); + } + + @Override + public int getWidth() { + return variable1.getWidth()+1+ (drawSignum() ? Utils.getPlainTextWidth(simbolo())+1 : 0) +variable2.getWidth(); + } + + @Override + public int getHeight(boolean small) { + Funzione tmin = variable1; + Funzione tmax = variable1; + if (tmin == null || variable2.getLine(small) >= tmin.getLine(small)) { + tmin = variable2; + } + if (tmax == null || variable2.getHeight(small) - variable2.getLine(small) >= tmax.getHeight(small) - tmax.getLine(small)) { + tmax = variable2; + } + return tmin.getLine(small) + tmax.getHeight(small) - tmax.getLine(small); + } + + @Override + public int getLine(boolean small) { + Funzione tl = variable1; + if (tl == null || variable2.getLine(small) >= tl.getLine(small)) { + tl = variable2; + } + return tl.getLine(small); + } + + @Override + public String toString() { + try { + return calcola().toString(); + } catch (Errore e) { + return e.id.toString(); + } + } + + @Override + public FunzioneDueValori clone() { + Cloner cloner = new Cloner(); + return cloner.deepClone(this); + } + + public boolean drawSignum() { + return true; + } +} diff --git a/src/org/warpgate/pi/calculator/FunzioneMultipla.java b/src/org/warpgate/pi/calculator/FunzioneMultipla.java index b6e04b56..20292b74 100644 --- a/src/org/warpgate/pi/calculator/FunzioneMultipla.java +++ b/src/org/warpgate/pi/calculator/FunzioneMultipla.java @@ -1,54 +1,71 @@ -package org.warpgate.pi.calculator; - -import java.util.Arrays; -import java.util.List; - -public abstract class FunzioneMultipla implements Funzione { - public FunzioneMultipla() { - setVariables(new Funzione[]{}); - } - public FunzioneMultipla(Funzione[] values) { - setVariables(values); - } - protected Funzione[] variables; - public Funzione[] getVariables() { - return variables; - } - public void setVariables(Funzione[] value) { - variables = value; - } - public void setVariables(final List value) { - int vsize = value.size(); - Funzione[] tmp = new Funzione[vsize]; - for (int i = 0; i < vsize; i++) { - tmp[i] = value.get(i); - } - variables = tmp; - } - - public Funzione getVariable(int index) { - return variables[index]; - } - public void setVariable(int index, Funzione value) { - variables[index] = value; - } - - public void addVariableToEnd(Funzione value) { - int index = variables.length; - setVariablesLength(index+1); - variables[index] = value; - } - - public int getVariablesLength() { - return variables.length; - } - - public void setVariablesLength(int length) { - variables = Arrays.copyOf(variables, length); - } - - @Override - public abstract String simbolo(); - @Override - public abstract Termine calcola() throws Errore; -} +package org.warpgate.pi.calculator; + +import java.util.Arrays; +import java.util.List; + +import com.rits.cloning.Cloner; + +public abstract class FunzioneMultipla implements Funzione { + public FunzioneMultipla() { + setVariables(new Funzione[]{}); + } + public FunzioneMultipla(Funzione[] values) { + setVariables(values); + } + protected Funzione[] variables; + public Funzione[] getVariables() { + return variables; + } + public void setVariables(Funzione[] value) { + variables = value; + } + public void setVariables(final List value) { + int vsize = value.size(); + Funzione[] tmp = new Funzione[vsize]; + for (int i = 0; i < vsize; i++) { + tmp[i] = value.get(i); + } + variables = tmp; + } + + public Funzione getVariable(int index) { + return variables[index]; + } + public void setVariable(int index, Funzione value) { + variables[index] = value; + } + + public void addVariableToEnd(Funzione value) { + int index = variables.length; + setVariablesLength(index+1); + variables[index] = value; + } + + public int getVariablesLength() { + return variables.length; + } + + public void setVariablesLength(int length) { + variables = Arrays.copyOf(variables, length); + } + + @Override + public abstract String simbolo(); + @Override + public abstract Termine calcola() throws Errore; + + @Override + public String toString() { + try { + return calcola().toString(); + } catch (Errore e) { + return e.id.toString(); + } + } + + @Override + public Funzione clone() { + Cloner cloner = new Cloner(); + return cloner.deepClone(this); + } +} diff --git a/src/org/warpgate/pi/calculator/FunzioneSingola.java b/src/org/warpgate/pi/calculator/FunzioneSingola.java deleted file mode 100644 index 8296dc5d..00000000 --- a/src/org/warpgate/pi/calculator/FunzioneSingola.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.warpgate.pi.calculator; - -import org.nevec.rjm.BigSurdVec; - -public abstract class FunzioneSingola implements Funzione { - public FunzioneSingola(Funzione value) { - setVariable(value); - } - protected Funzione variable = new Termine(BigSurdVec.ZERO); - public Funzione getVariable() { - return variable; - } - public void setVariable(Funzione value) { - variable = value; - } - @Override - public abstract String simbolo(); - @Override - public abstract Termine calcola() throws Errore; -} diff --git a/src/org/warpgate/pi/calculator/Main.java b/src/org/warpgate/pi/calculator/Main.java index 7decd2bf..e1f12604 100644 --- a/src/org/warpgate/pi/calculator/Main.java +++ b/src/org/warpgate/pi/calculator/Main.java @@ -1,27 +1,216 @@ -package org.warpgate.pi.calculator; - -public class Main { - public static void main(String[] args) { - Calculator c = new Calculator(false); - try { - long start = System.nanoTime(); - Termine result = c.calcolarisultato("((5^2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21"); - long end = System.nanoTime(); - long timeElapsed = end-start; - System.out.println("RESULT: " + result); - System.out.println("DECIMAl RESULT: " + result.getTerm().toBigDecimal()); - System.out.println("Time elapsed: " + (double) timeElapsed / 1000000000 + "\n"); - - - start = System.nanoTime(); - RisultatoEquazione eresult = c.calcolaequazione("((5^2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21=(175*(2√7)+3*(2√13))/105"); - end = System.nanoTime(); - timeElapsed = end-start; - System.out.println("Is an equation: " + eresult.isAnEquation); - System.out.println("L-R: " + eresult.LR); - System.out.println("Time elapsed: " + (((double) timeElapsed / 1000000000)) + "\n"); - } catch (Errore e) { - System.err.println(e.id); - } - } -} +package org.warpgate.pi.calculator; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferStrategy; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import org.gatecraft.game2d.utils.BitmapImage; +import org.nevec.rjm.NumeroAvanzato; +import org.nevec.rjm.NumeroAvanzatoVec; +import org.nevec.rjm.Rational; +import org.warp.engine.ActionInterface; +import org.warp.engine.Display; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; +import javafx.event.Event; +import javafx.event.EventHandler; +import javafx.util.Duration; + +public class Main implements ActionInterface { + public static final int[] screenSize = new int[]{300, 150}; + public static final int screenScale = 1; + public volatile static Display d; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Main() { + Display.start(this, screenSize[0], screenSize[1]); + d = Display.INSTANCE; + d.g().setFill(new javafx.scene.paint.Color(0.796875, 0.90234375, 0.828125, 1)); + d.g().fillRect(0, 0, screenSize[0], screenSize[0]); + Utils.writeLetter(d, "Loading...".toUpperCase(), (screenSize[0]-Utils.getPlainTextWidth("Loading...".toUpperCase()))/2, (screenSize[1]-Utils.getFontHeight(false))/2, false); + + try { + //Parentesi f = new Parentesi("(Ⓐ(2X)*3Y)/(5Z^2)+(Ⓐ(11A)*13B)/(7CZ)=19XZ"); + //PARENTESI CON CALCOLI + //Funzione f = new Sottrazione(new Somma(new Parentesi("Ⓐ9/2+Ⓐ7/2", "").calcola(), new Termine("3.5")), new Parentesi("3*2√14","").calcola()); + //PARENTESI CON DUE NUMERI FRAZIONALI COMPLETI CON INCOGNITE: + //Funzione f = new Parentesi("(Ⓐ(2X)*3Y)/(5Z^2)+(Ⓐ(11A)*13B)/(7CZ)", ""); + //PARENTESI CON DUE NUMERI FRAZIONALI DISALLINEATI GRAFICAMENTE: + //Funzione f = new Parentesi("((5^2-1)/2)/5-5/(5/2)=2", ""); + //TERMINE DI PROVA COMPLETO: + //Funzione f = new Termine(new NumeroAvanzato(new Rational(3, 2), new Rational(7, 1), new Incognite(new Incognita('X', Rational.ONE)), new Incognite(new Incognita('Y', Rational.ONE)), new Incognite(new Incognita('z', Rational.ONE)))); + //PARENTESI REALISTICA CON INCOGNITE: + //Funzione f = new Equazione(new Parentesi("X^2+(MX-M+4)^2-4X-4(MX-M+4)^2+7", ""), new Termine("0")); + //POTENZA: + //Funzione f = new Parentesi("(MX-M+4)^2", ""); + //NUMERO SEMPLICE LUNGO: + //Funzione f = new Parentesi("-1219999799999996934.42229", ""); + //: + //Funzione f = new Parentesi("5Y+XY=2", "") + equazione = ""; + c = new Calculator(true); + f = new Parentesi(equazione); + f2 = f.calcolaSistema(); + + + ew1 = f.getWidth(); + ew2 = f2.getWidth(); + eh2 = f2.getHeight(false); + x1 = 2; + x2 = 2; + requiresleep1 = false; + requiresleep2 = false; + aftersleep = false; + autoscroll = false; + + final Timeline timeline = new Timeline(); + timeline.setCycleCount(Timeline.INDEFINITE); + timeline.setAutoReverse(true); + timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000/25), new EventHandler() { + @Override + public void handle(Event arg0) { + refresh(); + } + })); + timeline.play(); + /* + long start = System.nanoTime(); + Termine result = c.calcolarisultato("((5^2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21"); + long end = System.nanoTime(); + long timeElapsed = end-start; + System.out.println("RESULT: " + result); + System.out.println("DECIMAl RESULT: " + result.getTerm().toBigDecimal()); + System.out.println("Time elapsed: " + (double) timeElapsed / 1000000000 + "\n"); + + + start = System.nanoTime(); + RisultatoEquazione eresult = c.calcolaequazione("((5^2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21=(175*(2√7)+3*(2√13))/105"); + end = System.nanoTime(); + timeElapsed = end-start; + System.out.println("Is an equation: " + eresult.isAnEquation); + System.out.println("L-R: " + eresult.LR); + System.out.println("Time elapsed: " + (((double) timeElapsed / 1000000000)) + "\n"); + */ + } catch (Errore e) { + d.setColor(new Color(204, 231, 212)); + d.fillRect(0, 0, screenSize[0], screenSize[1]); + + Utils.writeLetter(d, e.id.toString(), 2, 2, false); + + System.err.println(e.id); + } + } + + public static volatile String equazione = ""; + public static Calculator c; + public static Parentesi f; + public static Funzione f2; + public static int ew1; + public static int ew2; + public static int eh2; + public static int x1; + public static int x2; + public static boolean requiresleep1; + public static boolean requiresleep2; + public static boolean aftersleep; + public static boolean autoscroll; + + protected static void refresh() { + long delta = System.currentTimeMillis(); + d.setColor(new Color(204, 231, 212)); + d.fillRect(0, 0, screenSize[0], screenSize[1]); + + if (equazione == "") { + d.setColor(Color.BLACK); + d.drawString("Scrivi qua sopra un'espressione,".toUpperCase(), 10, 20); + d.drawString("dopodiche premi il tasto execute".toUpperCase(), 10, 35); + d.setColor(Color.RED); + d.drawBoldString( "Leggi ATTENZIONE.txt!".toUpperCase(), 10, 60); + } else { + if (ew1 + x1 + 5 > screenSize[0] && !requiresleep1 && autoscroll) { + x1-=1; + } else if(autoscroll) { + requiresleep1 = true; + } + + if (ew2 + x2 + 5 > screenSize[0] && !requiresleep2 && autoscroll) { + x2-=1; + } else if(autoscroll) { + requiresleep2 = true; + } + + if (requiresleep1 && requiresleep2 && autoscroll) { + requiresleep1 = false; + requiresleep2 = false; + try { + Thread.sleep(500); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + x1 = 2; + x2 = 2; + aftersleep = true; + } + + f.draw(x1,2,d, false); + f2.draw(x2,screenSize[1]-2-eh2,d, false); + } + + if (aftersleep && autoscroll) { + aftersleep = false; + try { + Thread.sleep(500); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + try { + delta = System.currentTimeMillis() - delta; + if (50-delta > 0 && autoscroll) { + Thread.sleep(50-delta); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static void main(String[] args) throws InterruptedException { + new Main(); + } + + @Override + public synchronized void refresh(String args) { + equazione = args.replace("sqrt", "Ⓐ").replace("^", "Ⓑ"); + c = new Calculator(true); + try { + f = new Parentesi(equazione); + } catch (Errore e) { + e.printStackTrace(); + } + try { + f2 = f.calcolaSistema(); + } catch (Errore e) { + e.printStackTrace(); + } + ew1 = f.getWidth(); + ew2 = f2.getWidth(); + eh2 = f2.getHeight(false); + x1 = 2; + x2 = 2; + requiresleep1 = false; + requiresleep2 = false; + aftersleep = false; + autoscroll = false; + } +} diff --git a/src/org/warpgate/pi/calculator/Moltiplicazione.java b/src/org/warpgate/pi/calculator/Moltiplicazione.java index b17c6a7b..773ddaa6 100644 --- a/src/org/warpgate/pi/calculator/Moltiplicazione.java +++ b/src/org/warpgate/pi/calculator/Moltiplicazione.java @@ -1,18 +1,84 @@ -package org.warpgate.pi.calculator; - -public class Moltiplicazione extends FunzioneDueValori { - - public Moltiplicazione(Funzione value1, Funzione value2) { - super(value1, value2); - } - - @Override - public String simbolo() { - return Simboli.MULTIPLICATION; - } - - @Override - public Termine calcola() throws Errore { - return getVariable1().calcola().multiply(getVariable2().calcola()); - } +package org.warpgate.pi.calculator; + +import java.awt.Graphics; +import java.math.BigInteger; + +import org.nevec.rjm.NumeroAvanzatoVec; + +public class Moltiplicazione extends FunzioneDueValori { + + public Moltiplicazione(Funzione value1, Funzione value2) { + super(value1, value2); + } + + @Override + public String simbolo() { + return Simboli.MULTIPLICATION; + } + + @Override + public Termine calcola() throws Errore { + return getVariable1().calcola().multiply(getVariable2().calcola()); + } + + @Override + public boolean drawSignum() { + Funzione[] tmpVar = new Funzione[]{variable1, variable2}; + boolean[] ok = new boolean[]{false, false}; + for (int val = 0; val < 2; val++) { + while (!ok[val]) { + if (tmpVar[val] instanceof Divisione) { + ok[0] = true; + ok[1] = true; + } else if (tmpVar[val] instanceof Incognita) { + ok[val] = true; + } else if (tmpVar[val] instanceof Termine) { + if (val == 0) { + ok[val] = true; + } else { + if (!(tmpVar[0] instanceof Termine)) { + ok[val] = true; + } else { + if (((Termine)tmpVar[0]).term.isBigInteger(false)) { + if (((Termine)tmpVar[val]).term.toBigInteger(true).compareTo(new BigInteger("1")) == 0) { + if (((Termine)tmpVar[val]).term.toNumeroAvanzato().getIncognitey().count() > 0) { + ok[val] = true; + } else { + break; + } + } else { + break; + } + } else { + ok[val] = true; + } + } + } + } else if (tmpVar[val] instanceof Potenza) { + tmpVar[val] = ((Potenza)tmpVar[val]).variable1; + } else if (tmpVar[val] instanceof Radice) { + ok[val] = true; + } else if (tmpVar[val] instanceof RadiceQuadrata) { + ok[val] = true; + } else if (tmpVar[val] instanceof Parentesi) { + ok[0] = true; + ok[1] = true; + } else if (tmpVar[val] instanceof FunzioneDueValori) { + if (val == 0) { + tmpVar[val] = ((FunzioneDueValori)tmpVar[val]).variable2; + } else { + tmpVar[val] = ((FunzioneDueValori)tmpVar[val]).variable1; + } + } else if (tmpVar[val] instanceof FunzioneAnteriore) { + tmpVar[val] = ((FunzioneAnteriore)tmpVar[val]).variable; + } + } + } + + if (ok[0] == true && ok[1] == true) { + return false; + } else { + return true; + } + } } \ No newline at end of file diff --git a/src/org/warpgate/pi/calculator/Parentesi.java b/src/org/warpgate/pi/calculator/Parentesi.java index 96905577..2548fb07 100644 --- a/src/org/warpgate/pi/calculator/Parentesi.java +++ b/src/org/warpgate/pi/calculator/Parentesi.java @@ -1,347 +1,638 @@ -package org.warpgate.pi.calculator; - -import static org.warpgate.pi.calculator.Utils.ArrayToRegex; -import static org.warpgate.pi.calculator.Utils.concat; - -import java.util.ArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.nevec.rjm.BigSurdVec; - -public class Parentesi extends FunzioneMultipla { - - public Parentesi() { - super(); - } - - public Parentesi(Funzione[] values) { - super(values); - } - - public Parentesi(String string, String debugSpaces) throws Errore { - super(); - try{ - //Se l'espressione è già un numero: - setVariables(new Funzione[]{new Termine(string)}); - Utils.debug.println(debugSpaces+"•Result:"+string); - } catch (NumberFormatException ex) { - String processExpression = string; - - Utils.debug.println(debugSpaces+"•Analyzing expression:"+processExpression); - debugSpaces+= " "; - - //Se l'espressione non è già un numero: - - //Correggi i segni ++ e -- in eccesso - Pattern pattern = Pattern.compile("\\+\\++?|\\-\\-+?"); - Matcher matcher = pattern.matcher(processExpression); - boolean cambiati = false; - while (matcher.find()) { - cambiati = true; - String correzione = "+"; - processExpression = processExpression.substring(0, matcher.start(0)+1)+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); - matcher = pattern.matcher(processExpression); - } - - //Correggi i segni +- e -+ in eccesso - pattern = Pattern.compile("\\+\\-|\\-\\+"); - matcher = pattern.matcher(processExpression); - while (matcher.find()) { - cambiati = true; - String correzione = "-"; - processExpression = processExpression.substring(0, matcher.start(0)+1)+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); - matcher = pattern.matcher(processExpression); - } - - //Rimuovi i segni appena dopo le parentesi - if (processExpression.contains("(+")) { - cambiati = true; - processExpression = processExpression.replace("(+", "("); - } - //Rimuovi i segni appena dopo l'inizio - if (processExpression.startsWith("+")) { - cambiati = true; - processExpression = processExpression.substring(1, processExpression.length()); - } - - //Rimuovi i + in eccesso - pattern = Pattern.compile("["+ - ArrayToRegex(Utils.add(concat(Simboli.segni(true), Simboli.funzioni()), "(")) - +"]\\+[^"+ - ArrayToRegex(concat(concat(Simboli.segni(true), Simboli.funzioni()), new String[]{"(", ")"})) - +"]+?["+ - ArrayToRegex(concat(Simboli.segni(true), Simboli.funzioni())) - +"]|["+ - ArrayToRegex(concat(Simboli.segni(true), Simboli.funzioni())) - +"]+?\\+[^"+ - ArrayToRegex(concat(concat(Simboli.segni(true), Simboli.funzioni()), new String[]{"(", ")"})) - +"]"); - matcher = pattern.matcher(processExpression); - cambiati = false; - while (matcher.find()) { - cambiati = true; - String correzione = matcher.group(0).replaceFirst(Matcher.quoteReplacement("+"), ""); - processExpression = processExpression.substring(0, matcher.start(0)+1)+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); - matcher = pattern.matcher(processExpression); - } - - //Correggi i segni - in +- - pattern = Pattern.compile("[^"+Utils.ArrayToRegex(concat(concat(Simboli.funzioni(),Simboli.parentesi()), Simboli.segni(true)))+"]-"); - matcher = pattern.matcher(processExpression); - while (matcher.find()) { - cambiati = true; - String correzione = "+-"; - processExpression = processExpression.substring(0, matcher.start(0)+1)+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); - matcher = pattern.matcher(processExpression); - } - - if (cambiati) { - Utils.debug.println(debugSpaces+"•Resolved signs:"+processExpression); - } - - //Aggiungi i segni * accanto alle parentesi - pattern = Pattern.compile("\\([^\\(]+?\\)"); - matcher = pattern.matcher(processExpression); - cambiati = false; - while (matcher.find()) { - cambiati = true; - //sistema i segni * impliciti prima e dopo l'espressione. - String beforeexp = processExpression.substring(0, matcher.start(0)); - String newexp = matcher.group(0).substring(1, matcher.group(0).length()-1); - String afterexp = processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); - if (Pattern.compile("[^"+Utils.ArrayToRegex(Utils.add(concat(Simboli.funzioni(), Simboli.segni(true)), "("))+"]$").matcher(beforeexp).find()) { - //Se la stringa precedente finisce con un numero - beforeexp += "*"; - } - if (Pattern.compile("^[^"+Utils.ArrayToRegex(Utils.add(concat(Simboli.funzioni(), Simboli.segni(true)), ")"))+"]").matcher(afterexp).find()) { - //Se la stringa successiva inizia con un numero - afterexp = "*"+afterexp; - } - processExpression = beforeexp+"⑴"+newexp+"⑵"+afterexp; - matcher = pattern.matcher(processExpression); - } - - processExpression = processExpression.replace("⑴", "(").replace("⑵", ")"); - - if (cambiati) { - Utils.debug.println(debugSpaces+"•Added implicit multiplications:"+processExpression); - } - - Utils.debug.println(debugSpaces+"•Subdivision in classes:"); - - debugSpaces += " "; - - - //Suddividi tutto - Parentesi parentesiNonSuddivisaCorrettamente = new Parentesi(); - parentesiNonSuddivisaCorrettamente.setVariables(new Funzione[]{}); - String tmp = ""; - final String[] funzioni = concat(concat(Simboli.funzioni(), Simboli.parentesi()), Simboli.segni(true)); - for (int i = 0; i < processExpression.length(); i++) { - //Per ogni carattere cerca se è un numero o una funzione: - String charI = processExpression.charAt(i)+""; - if (Utils.isInArray(charI, funzioni)) { - - //Cerca il tipo di funzione tra le esistenti - Funzione f = null; - switch (charI) { - case Simboli.SUM: - f = new Somma(null, null); - break; - case Simboli.MULTIPLICATION: - f = new Moltiplicazione(null, null); - break; - case Simboli.DIVISION: - f = new Divisione(null, null); - break; - case Simboli.NTH_ROOT: - f = new Radice(null, null); - break; - case Simboli.SQUARE_ROOT: - f = new RadiceQuadrata(null); - break; - case Simboli.POTENZA: - f = new Potenza(null, null); - break; - case Simboli.PARENTHESIS_OPEN: - //cerca l'ultima parentesi chiusa - int startIndex = i; - int endIndex = -1; - int jumps = -1; - for (int i2 = startIndex; i2 < processExpression.length(); i2++) { - if ((processExpression.charAt(i2)+"").equals(Simboli.PARENTHESIS_CLOSE)) { - if (jumps == 0) { - endIndex = i2; - break; - } else if (jumps > 0) { - jumps -= 1; - } else if (jumps < 0) { - throw new Errore(Errori.UNBALANCED_BRACKETS); - } - } else if ((processExpression.charAt(i2)+"").equals(Simboli.PARENTHESIS_OPEN)) { - jumps +=1; - } - } - if (endIndex == -1 || endIndex < startIndex) { - throw new Errore(Errori.UNBALANCED_BRACKETS); - } - startIndex += 1; - i = startIndex; - - String tmpExpr = ""; - while (i < endIndex) { - tmpExpr += processExpression.charAt(i); - i++; - } - f = new Parentesi(tmpExpr, debugSpaces); - break; - default: - throw new java.lang.RuntimeException("Il carattere "+charI+" non è tra le funzioni designate!\nAggiungerlo ad esse o rimuovere il carattere dall'espressione!"); - } - if (f instanceof Parentesi) { - tmp = ""; - } else { - if (tmp.length() != 0) { - parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp)); - Utils.debug.println(debugSpaces+"•Added variable to expression:"+tmp); - } - } - parentesiNonSuddivisaCorrettamente.addVariableToEnd(f); - Utils.debug.println(debugSpaces+"•Added variable to expression:"+f.simbolo()); - tmp = ""; - } else { - try{ - if (!(charI.equals("-") || charI.equals("."))) { - Double.parseDouble(tmp + charI); - } - //Se il carattere è un numero intero, un segno negativo, o un punto - tmp += charI; - } catch (NumberFormatException exc) { - throw new java.lang.RuntimeException("Il carattere "+tmp+charI+" non è nè un numero nè un espressione presente nella lista completa!\nAggiungerlo ad essa o rimuovere il carattere dall'espressione!"); - } - } - } - if (tmp.length() > 0) { - Utils.debug.println(debugSpaces+"•Added variable to expression:"+tmp); - parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp)); - tmp = ""; - } - - int dsl = debugSpaces.length();debugSpaces = "";for (int i = 0; i < dsl-2; i++) {debugSpaces += " ";} - Utils.debug.println(debugSpaces+"•Finished the subdivision in classes."); - - //Fine suddivisione di insieme - - //Inizia l'affinazione dell'espressione - Utils.debug.println(debugSpaces+"•Pushing classes..."); - - Funzione[] funzioniOLDArray = parentesiNonSuddivisaCorrettamente.getVariables(); - ArrayList funzioniOLD = new ArrayList(); - for (int i = 0; i < funzioniOLDArray.length; i++) { - if (funzioniOLDArray[i] != null) { - funzioniOLD.add(funzioniOLDArray[i]); - } - } - - Utils.debug.println(debugSpaces+"•Correcting classes:"); - - debugSpaces += " "; - - int before = 0; - String fase = "funzioniSN"; - int n = 0; - do { - before = funzioniOLD.size(); - int i = 0; - boolean change = false; - if (Utils.ciSonoSoloNumeriESomme(funzioniOLD)) { - fase = "somme"; //QUARTA FASE - } else if (Utils.ciSonoFunzioniSNnonImpostate(funzioniOLD)) { - fase = "funzioniSN"; // PRIMA FASE - } else if (Utils.ciSonoAltreFunzioni(funzioniOLD)) { - fase = "funzioniNSN"; //SECONDA FASE - } else { - fase = "moltiplicazioni"; //TERZA FASE - } - while (i < funzioniOLD.size() && change == false) { - Funzione funzioneTMP = funzioniOLD.get(i); - if (funzioneTMP instanceof FunzioneDueValori) { - if (fase != "funzioniSN") { - if ( - fase == "somme" && (funzioneTMP instanceof Somma) == true - || - (fase == "moltiplicazioni" && (funzioneTMP instanceof Somma) == false) - || - (fase == "funzioniNSN" && (funzioneTMP instanceof Somma) == false && (funzioneTMP instanceof Moltiplicazione) == false && (funzioneTMP instanceof Divisione) == false) - ) { - change = true; - if (i+1 < funzioniOLD.size() && i-1 >= 0 ) { - ((FunzioneDueValori) funzioneTMP).setVariable1(funzioniOLD.get(i-1)); - ((FunzioneDueValori) funzioneTMP).setVariable2(funzioniOLD.get(i+1)); - funzioniOLD.set(i, funzioneTMP.calcola()); - - //è importante togliere prima gli elementi in fondo e poi quelli davanti, perché gli indici scalano da destra a sinistra. - funzioniOLD.remove(i+1); - funzioniOLD.remove(i-1); - - Utils.debug.println(debugSpaces+"•Set variable to expression:"+funzioneTMP.simbolo()); - Utils.debug.println(debugSpaces+" "+"var1="+((FunzioneDueValori) funzioneTMP).getVariable1().calcola()); - Utils.debug.println(debugSpaces+" "+"var2="+((FunzioneDueValori) funzioneTMP).getVariable2().calcola()); - Utils.debug.println(debugSpaces+" "+"(result)="+((FunzioneDueValori) funzioneTMP).calcola()); - } else { - throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!"); - } - } - } - } else if (funzioneTMP instanceof FunzioneSingola) { - if (fase == "funzioniSN") { - change = true; - if (i+1 < funzioniOLD.size()) { - ((FunzioneSingola) funzioneTMP).setVariable(funzioniOLD.get(i+1)); - funzioniOLD.set(i, funzioneTMP); - - //è importante togliere prima gli elementi in fondo e poi quelli davanti, perché gli indici scalano da destra a sinistra. - funzioniOLD.remove(i+1); - - Utils.debug.println(debugSpaces+"•Set variable to expression:"+funzioneTMP.simbolo()); - Utils.debug.println(debugSpaces+" "+"var="+((FunzioneSingola) funzioneTMP).getVariable().calcola()); - } else { - throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!"); - } - } - } else if (funzioneTMP instanceof Termine || funzioneTMP instanceof Parentesi) { - if (n < 300) { - //Utils.debug.println(debugSpaces+"•Set variable to number:"+funzioneTMP.calcola()); - } - } else { - throw new java.lang.RuntimeException("Tipo sconosciuto"); - } - i++; - n++; - } - } while (funzioniOLD.size() != before || fase != "somme"); - setVariables(funzioniOLD); - - dsl = debugSpaces.length();debugSpaces = "";for (int i = 0; i < dsl-2; i++) {debugSpaces += " ";} - Utils.debug.println(debugSpaces+"•Finished correcting classes."); - - Utils.debug.println(debugSpaces+"•Result:"+calcola()); - } - } - - @Override - public String simbolo() { - return "Parentesi"; - } - - @Override - public Termine calcola() throws Errore { - Termine result = new Termine(BigSurdVec.ZERO); - for (Funzione f : variables) { - result = result.add(f.calcola()); - } - return result; - } - -} +package org.warpgate.pi.calculator; + +import static org.warpgate.pi.calculator.Utils.ArrayToRegex; +import static org.warpgate.pi.calculator.Utils.concat; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.nevec.rjm.NumeroAvanzato; +import org.nevec.rjm.NumeroAvanzatoVec; +import org.warp.engine.Display; + +public class Parentesi extends FunzioneMultipla { + + public Parentesi() { + super(); + } + + public Parentesi(Funzione[] values) { + super(values); + } + + private boolean parentesiIniziale = false; + + public Parentesi(String string) throws Errore { + this(string, "", true); + } + + public Parentesi(String string, String debugSpaces, boolean parentesiIniziale) throws Errore { + super(); + this.parentesiIniziale = parentesiIniziale; + try{ + //Se l'espressione è già un numero: + setVariables(new Funzione[]{new Termine(string)}); + Utils.debug.println(debugSpaces+"•(Value:"+string+")"); + } catch (NumberFormatException ex) { + String processExpression = string; + + Utils.debug.println(debugSpaces+"•Analyzing expression:"+processExpression); + debugSpaces+= " "; + + //Se l'espressione non è già un numero: + + //Controlla se ci sono più di un uguale + int equationsFound = 0; + int systemsFound = 0; + for (char c : processExpression.toCharArray()) { + if ((""+c).equals(Simboli.EQUATION)) { + equationsFound+=1; + } + if ((""+c).equals(Simboli.SYSTEM)) { + equationsFound+=1; + } + } + if (equationsFound == 1 && systemsFound == 0) { + processExpression = Simboli.SYSTEM+processExpression; + systemsFound+=1; + } + if (equationsFound != systemsFound) { + throw new Errore(Errori.SYNTAX_ERROR); + } + + //Correggi i segni ++ e -- in eccesso + Pattern pattern = Pattern.compile("\\+\\++?|\\-\\-+?"); + Matcher matcher = pattern.matcher(processExpression); + boolean cambiati = false; + while (matcher.find()) { + cambiati = true; + String correzione = "+"; + processExpression = processExpression.substring(0, matcher.start(0)+1)+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); + matcher = pattern.matcher(processExpression); + } + + //Correggi i segni +- e -+ in eccesso + pattern = Pattern.compile("\\+\\-|\\-\\+"); + matcher = pattern.matcher(processExpression); + while (matcher.find()) { + cambiati = true; + String correzione = "-"; + processExpression = processExpression.substring(0, matcher.start(0))+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); + matcher = pattern.matcher(processExpression); + } + + //Rimuovi i segni appena dopo le parentesi + if (processExpression.contains("(+")) { + cambiati = true; + processExpression = processExpression.replace("(+", "("); + } + + //Cambia i segni appena prima le parentesi + if (processExpression.contains("-(")) { + cambiati = true; + processExpression = processExpression.replace("-(", "-1*("); + } + //Rimuovi i segni appena dopo l'inizio + if (processExpression.startsWith("+")) { + cambiati = true; + processExpression = processExpression.substring(1, processExpression.length()); + } + + //Rimuovi i + in eccesso + pattern = Pattern.compile("["+ + ArrayToRegex(Utils.add(concat(Simboli.segni(true), Simboli.funzioni()), "(")) + +"]\\+[^"+ + ArrayToRegex(concat(concat(Simboli.segni(true), Simboli.funzioni()), new String[]{"(", ")"})) + +"]+?["+ + ArrayToRegex(concat(Simboli.segni(true), Simboli.funzioni())) + +"]|["+ + ArrayToRegex(concat(Simboli.segni(true), Simboli.funzioni())) + +"]+?\\+[^"+ + ArrayToRegex(concat(concat(Simboli.segni(true), Simboli.funzioni()), new String[]{"(", ")"})) + +"]"); + matcher = pattern.matcher(processExpression); + cambiati = false; + while (matcher.find()) { + cambiati = true; + String correzione = matcher.group(0).replaceFirst(Matcher.quoteReplacement("+"), ""); + processExpression = processExpression.substring(0, matcher.start(0)+1)+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); + matcher = pattern.matcher(processExpression); + } + + //Correggi i segni - in +- + pattern = Pattern.compile("[^"+Utils.ArrayToRegex(concat(concat(Simboli.funzioni(),new String[]{Simboli.PARENTHESIS_OPEN}), Simboli.segni(true)))+"]-"); + matcher = pattern.matcher(processExpression); + while (matcher.find()) { + cambiati = true; + String correzione = "+-"; + processExpression = processExpression.substring(0, matcher.start(0)+1)+correzione+processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); + matcher = pattern.matcher(processExpression); + } + + if (cambiati) { + Utils.debug.println(debugSpaces+"•Resolved signs:"+processExpression); + } + + //Aggiungi i segni * accanto alle parentesi + pattern = Pattern.compile("\\([^\\(]+?\\)"); + matcher = pattern.matcher(processExpression); + cambiati = false; + while (matcher.find()) { + cambiati = true; + //sistema i segni * impliciti prima e dopo l'espressione. + String beforeexp = processExpression.substring(0, matcher.start(0)); + String newexp = matcher.group(0).substring(1, matcher.group(0).length()-1); + String afterexp = processExpression.substring(matcher.start(0)+matcher.group(0).length(), processExpression.length()); + if (Pattern.compile("[^\\-"+Utils.ArrayToRegex(Utils.add(concat(Simboli.funzioni(), concat(Simboli.segni(true), Simboli.sintassiGenerale())), "("))+"]$").matcher(beforeexp).find()) { + //Se la stringa precedente finisce con un numero + beforeexp += Simboli.MULTIPLICATION; + } + if (Pattern.compile("^[^\\-"+Utils.ArrayToRegex(Utils.add(concat(Simboli.funzioni(), concat(Simboli.segni(true), Simboli.sintassiGenerale())), ")"))+"]").matcher(afterexp).find()) { + //Se la stringa successiva inizia con un numero + afterexp = Simboli.MULTIPLICATION+afterexp; + } + processExpression = beforeexp+"⑴"+newexp+"⑵"+afterexp; + matcher = pattern.matcher(processExpression); + } + + processExpression = processExpression.replace("⑴", "(").replace("⑵", ")"); + + if (cambiati) { + Utils.debug.println(debugSpaces+"•Added implicit multiplications:"+processExpression); + } + + Utils.debug.println(debugSpaces+"•Subdivision in classes:"); + + debugSpaces += " "; + + + //Suddividi tutto + Parentesi parentesiNonSuddivisaCorrettamente = new Parentesi(); + parentesiNonSuddivisaCorrettamente.setVariables(new Funzione[]{}); + String tmp = ""; + Incognite tmpI = new Incognite(); + final String[] funzioni = concat(concat(concat(concat(Simboli.funzioni(), Simboli.parentesi()), Simboli.segni(true)), Simboli.incognite()), Simboli.sintassiGenerale()); + for (int i = 0; i < processExpression.length(); i++) { + //Per ogni carattere cerca se è un numero o una funzione: + String charI = processExpression.charAt(i)+""; + if (Utils.isInArray(charI, funzioni)) { + + //Cerca il tipo di funzione tra le esistenti + Funzione f = null; + switch (charI) { + case Simboli.SUM: + f = new Somma(null, null); + break; + case Simboli.MULTIPLICATION: + f = new Moltiplicazione(null, null); + break; + case Simboli.DIVISION: + f = new Divisione(null, null); + break; + case Simboli.NTH_ROOT: + f = new Radice(null, null); + break; + case Simboli.SQUARE_ROOT: + f = new RadiceQuadrata(null); + break; + case Simboli.POTENZA: + f = new Potenza(null, null); + break; + case Simboli.EQUATION: + f = new Equazione(null, null); + break; + case Simboli.SYSTEM: + f = new ParteSistema(null); + break; + case Simboli.PARENTHESIS_OPEN: + //cerca l'ultima parentesi chiusa + int startIndex = i; + int endIndex = -1; + int jumps = -1; + for (int i2 = startIndex; i2 < processExpression.length(); i2++) { + if ((processExpression.charAt(i2)+"").equals(Simboli.PARENTHESIS_CLOSE)) { + if (jumps == 0) { + endIndex = i2; + break; + } else if (jumps > 0) { + jumps -= 1; + } else if (jumps < 0) { + throw new Errore(Errori.UNBALANCED_BRACKETS); + } + } else if ((processExpression.charAt(i2)+"").equals(Simboli.PARENTHESIS_OPEN)) { + jumps +=1; + } + } + if (endIndex == -1 || endIndex < startIndex) { + throw new Errore(Errori.UNBALANCED_BRACKETS); + } + startIndex += 1; + i = startIndex; + + String tmpExpr = ""; + while (i < endIndex) { + tmpExpr += processExpression.charAt(i); + i++; + } + f = new Parentesi(tmpExpr, debugSpaces, false); + break; + default: + if (Utils.isInArray(charI, Simboli.incognite())) { + //Fallback + NumeroAvanzato na = NumeroAvanzato.ONE; + Incognite iy = na.getIncognitey(); + iy.incognite.add(new Incognita(charI.charAt(0), 1, 1)); + na = na.setIncognitey(iy); + f = new Termine(na); + } else { + throw new java.lang.RuntimeException("Il carattere "+charI+" non è tra le funzioni designate!\nAggiungerlo ad esse o rimuovere il carattere dall'espressione!"); + } + } + if (f instanceof Parentesi) { + tmp = ""; + } else if (f instanceof Termine) { + if (parentesiNonSuddivisaCorrettamente.getVariablesLength() == 0) { + if (tmp.length() > 0) { + parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp)); + Utils.debug.println(debugSpaces+"•Added value to expression:"+tmp); + parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Moltiplicazione(null, null)); + Utils.debug.println(debugSpaces+"•Added variable to expression:"+new Moltiplicazione(null, null).simbolo()); + } + } else { + if (tmp.length() > 0) { + if (parentesiNonSuddivisaCorrettamente.getVariable(parentesiNonSuddivisaCorrettamente.getVariablesLength()-1) instanceof Termine) { + parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Moltiplicazione(null, null)); + Utils.debug.println(debugSpaces+"•Added variable to expression:"+new Moltiplicazione(null, null).simbolo()); + } + if (tmp.equals("-")) { + tmp = "-1"; + } + parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp)); + Utils.debug.println(debugSpaces+"•Added value to expression:"+tmp); + } + if (tmp.length() > 0 || parentesiNonSuddivisaCorrettamente.getVariable(parentesiNonSuddivisaCorrettamente.getVariablesLength()-1) instanceof Termine) { + parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Moltiplicazione(null, null)); + Utils.debug.println(debugSpaces+"•Added variable to expression:"+new Moltiplicazione(null, null).simbolo()); + } + } + } else { + if (tmp.length() != 0) { + parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp)); + Utils.debug.println(debugSpaces+"•Added variable to expression:"+tmp); + } + } + parentesiNonSuddivisaCorrettamente.addVariableToEnd(f); + Utils.debug.println(debugSpaces+"•Added variable to expression:"+f.simbolo()); + tmp = ""; + } else { + try{ + if (charI.equals("-") == false && charI.equals(".") == false) { + Double.parseDouble(tmp + charI); + } + //Se il carattere è un numero intero, un segno negativo, o un punto + tmp += charI; + } catch (NumberFormatException exc) { + throw new java.lang.RuntimeException("Il carattere "+tmp+charI+" non è nè un numero nè un espressione presente nella lista completa!\nAggiungerlo ad essa o rimuovere il carattere dall'espressione!"); + } + } + } + if (tmp.length() > 0) { + Utils.debug.println(debugSpaces+"•Added variable to expression:"+tmp); + parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp)); + tmp = ""; + } + + int dsl = debugSpaces.length();debugSpaces = "";for (int i = 0; i < dsl-2; i++) {debugSpaces += " ";} + Utils.debug.println(debugSpaces+"•Finished the subdivision in classes."); + //Fine suddivisione di insieme + + Utils.debug.println(debugSpaces+"•Removing useless parentheses"); + for (int i = 0; i < parentesiNonSuddivisaCorrettamente.variables.length; i++) { + if (parentesiNonSuddivisaCorrettamente.variables[i] instanceof Parentesi) { + Parentesi par = (Parentesi) parentesiNonSuddivisaCorrettamente.variables[i]; + if (par.variables.length == 1) { + Funzione subFunz = par.variables[0]; + if (subFunz instanceof Parentesi || subFunz instanceof Termine) { + parentesiNonSuddivisaCorrettamente.variables[i] = subFunz; + Utils.debug.println(debugSpaces+" •Useless parentheses removed"); + } + } + } + } + + //Inizia l'affinazione dell'espressione + Utils.debug.println(debugSpaces+"•Pushing classes..."); + + Funzione[] funzioniOLDArray = parentesiNonSuddivisaCorrettamente.getVariables(); + ArrayList funzioniOLD = new ArrayList(); + for (int i = 0; i < funzioniOLDArray.length; i++) { + if (funzioniOLDArray[i] != null) { + funzioniOLD.add(funzioniOLDArray[i]); + } + } + + Utils.debug.println(debugSpaces+" •Correcting classes:"); + + int before = 0; + String fase = "funzioniSN"; + int n = 0; + do { + before = funzioniOLD.size(); + int i = 0; + boolean change = false; + if (Utils.ciSonoFunzioniSNnonImpostate(funzioniOLD)) { + fase = "funzioniSN"; // PRIMA FASE + } else if (Utils.ciSonoFunzioniNSNnonImpostate(funzioniOLD)) { + fase = "funzioniNSN"; //SECONDA FASE + } else if (Utils.ciSonoMoltiplicazioniNonImpostate(funzioniOLD)) { + fase = "moltiplicazioni"; //TERZA FASE + } else if (Utils.ciSonoSommeNonImpostate(funzioniOLD)) { + fase = "somme"; //QUARTA FASE + } else if (Utils.ciSonoEquazioniNonImpostate(funzioniOLD)) { + fase = "equazioni"; //QUINTA FASE + } else if (Utils.ciSonoSistemiNonImpostati(funzioniOLD)) { + fase = "sistemi"; //SESTA FASE + } else { + System.out.println("errore?");//BOH + } + while (i < funzioniOLD.size() && change == false && funzioniOLD.size() > 1) { + Funzione funzioneTMP = funzioniOLD.get(i); + if (funzioneTMP instanceof FunzioneDueValori) { + if (fase != "funzioniSN") { + if ( + ( + fase == "somme" && (funzioneTMP instanceof Somma) == true + && + ( + ( + funzioneTMP instanceof FunzioneAnteriore + && + ((FunzioneAnteriore)funzioneTMP).variable == null + ) + || + ( + funzioneTMP instanceof FunzioneDueValori + && + ((FunzioneDueValori)funzioneTMP).variable1 == null + && + ((FunzioneDueValori)funzioneTMP).variable2 == null + ) + || + ( + !(funzioneTMP instanceof FunzioneAnteriore) + && + !(funzioneTMP instanceof FunzioneDueValori) + ) + ) + ) + || + ( + (fase == "moltiplicazioni" && (funzioneTMP instanceof Somma) == false) + && + ( + ( + funzioneTMP instanceof FunzioneAnteriore + && + ((FunzioneAnteriore)funzioneTMP).variable == null + ) + || + ( + funzioneTMP instanceof FunzioneDueValori + && + ((FunzioneDueValori)funzioneTMP).variable1 == null + && + ((FunzioneDueValori)funzioneTMP).variable2 == null + ) + || + ( + !(funzioneTMP instanceof FunzioneAnteriore) + && + !(funzioneTMP instanceof FunzioneDueValori) + ) + ) + ) + || + (fase == "equazioni" && funzioneTMP instanceof Equazione) + || + ( + fase == "funzioniNSN" + && + (funzioneTMP instanceof Somma) == false + && + (funzioneTMP instanceof Moltiplicazione) == false + && + (funzioneTMP instanceof Divisione) == false + && + ( + ( + funzioneTMP instanceof FunzioneAnteriore + && + ((FunzioneAnteriore)funzioneTMP).variable == null + ) + || + ( + funzioneTMP instanceof FunzioneDueValori + && + ((FunzioneDueValori)funzioneTMP).variable1 == null + && + ((FunzioneDueValori)funzioneTMP).variable2 == null + ) + || + ( + !(funzioneTMP instanceof FunzioneAnteriore) + && + !(funzioneTMP instanceof FunzioneDueValori) + ) + ) + ) + ) { + change = true; + + if (i+1 < funzioniOLD.size() && i-1 >= 0 ) { + ((FunzioneDueValori) funzioneTMP).setVariable1(funzioniOLD.get(i-1)); + ((FunzioneDueValori) funzioneTMP).setVariable2(funzioniOLD.get(i+1)); + funzioniOLD.set(i, funzioneTMP); + + //è importante togliere prima gli elementi in fondo e poi quelli davanti, perché gli indici scalano da destra a sinistra. + funzioniOLD.remove(i+1); + funzioniOLD.remove(i-1); + + Utils.debug.println(debugSpaces+" •Set variable to expression:"+funzioneTMP.simbolo()); + try {Utils.debug.println(debugSpaces+" "+"var1="+((FunzioneDueValori) funzioneTMP).getVariable1().calcola());} catch (NullPointerException ex2) {} + try {Utils.debug.println(debugSpaces+" "+"var2="+((FunzioneDueValori) funzioneTMP).getVariable2().calcola());} catch (NullPointerException ex2) {} + try {Utils.debug.println(debugSpaces+" "+"(result)="+((FunzioneDueValori) funzioneTMP).calcola());} catch (NullPointerException ex2) {} + + } else { + throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!"); + } + } + } + } else if (funzioneTMP instanceof FunzioneAnteriore) { + if ( + ( + fase == "funzioniSN" + && + ((FunzioneAnteriore) funzioneTMP).variable == null + ) + || + ( + fase == "sistemi" + && + funzioneTMP instanceof ParteSistema + ) + ) { + change = true; + if (i+1 < funzioniOLD.size()) { + ((FunzioneAnteriore) funzioneTMP).setVariable(funzioniOLD.get(i+1)); + funzioniOLD.set(i, funzioneTMP); + + //è importante togliere prima gli elementi in fondo e poi quelli davanti, perché gli indici scalano da destra a sinistra. + funzioniOLD.remove(i+1); + + Utils.debug.println(debugSpaces+" •Set variable to expression:"+funzioneTMP.simbolo()); + Utils.debug.println(debugSpaces+" "+"var="+((FunzioneAnteriore) funzioneTMP).getVariable().calcola().toString()); + } else { + throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!"); + } + } + } else if (funzioneTMP instanceof Termine || funzioneTMP instanceof Parentesi) { + if (n < 300) { + //Utils.debug.println(debugSpaces+" •Set variable to number:"+funzioneTMP.calcola()); + } + } else { + throw new java.lang.RuntimeException("Tipo sconosciuto"); + } + i++; + n++; + } + } while (((funzioniOLD.size() != before || fase != "sistemi") && funzioniOLD.size() > 1)); + setVariables(funzioniOLD); + + dsl = debugSpaces.length();debugSpaces = "";for (int i = 0; i < dsl-2; i++) {debugSpaces += " ";} + Utils.debug.println(debugSpaces+"•Finished correcting classes."); + + Termine result = calcola(); + Utils.debug.println(debugSpaces+"•Result:"+result); + } + } + + @Override + public String simbolo() { + return "Parentesi"; + } + + public ParteSistema calcolaSistema() throws Errore { + return new ParteSistema(calcolaEquazione()); + } + + public Equazione calcolaEquazione() throws Errore { + return new Equazione(calcola(), new Termine("0")); + } + + @Override + public Termine calcola() throws Errore { + if (variables.length == 0) { + return new Termine("0"); + } else if (variables.length == 1) { + return variables[0].calcola(); + } else { + Termine result = new Termine("0"); + for (Funzione f : variables) { + result = result.add(f.calcola()); + } + return result; + } + } + + @Override + public void draw(int x, int y, Display g, boolean small) { + if (parentesiIniziale && variables.length == 1) { + this.variables[0].draw(x, y, g, small); + } else { + float miny = y; + float maxy = y+getHeight(small); + int lw = Utils.getPlainTextWidth("(")+1; + int h = getHeight(small); + g.setColor(Color.BLACK); + if (small) { + g.draw45Line(x+3, y, x+2, y+1, true); + g.drawOrthoLine(x+2, y+1, x+2, y+h-2); + g.draw45Line(x+2, y+h-2, x+3, y+h-1, false); + } else { + g.draw45Line(x+3, y, x+1, y+2, true); + g.drawOrthoLine(x+1, y+2, x+1, y+h-3); + g.draw45Line(x+1, y+h-3, x+3, y+h-1, false); + } + x += lw; + for (Funzione f : variables) { + float fheight = f.getHeight(small); + float y2=miny+((maxy-miny)/2-fheight/2); + f.draw(x, (int) y2, g, small); + x+=f.getWidth(); + } + if (small) { + g.draw45Line(x+1, y, x+2, y+1, false); + g.drawOrthoLine(x+2, y+1, x+2, y+h-2); + g.draw45Line(x+2, y+h-2, x+1, y+h-1, true); + } else { + g.draw45Line(x+1, y, x+3, y+2, false); + g.drawOrthoLine(x+3, y+2, x+3, y+h-3); + g.draw45Line(x+3, y+h-3, x+1, y+h-1, true); + } + } + } + + @Override + public int getWidth() { + if (parentesiIniziale && variables.length == 1) { + return this.variables[0].getWidth(); + } else { + int w = 0; + int lw = Utils.getPlainTextWidth("(")+1; + for (Funzione f : variables) { + w+=f.getWidth(); + } + return w+lw*2; + } + } + + @Override + public int getHeight(boolean small) { + if (parentesiIniziale && variables.length == 1) { + return this.variables[0].getHeight(small); + } else { + Funzione tmin = null; + Funzione tmax = null; + for (Funzione t : variables) { + if (tmin == null || t.getLine(small) >= tmin.getLine(small)) { + tmin = t; + } + if (tmax == null || t.getHeight(small) - t.getLine(small) >= tmax.getHeight(small) - tmax.getLine(small)) { + tmax = t; + } + } + if (tmin == null) return Utils.getFontHeight(small); + return tmin.getLine(small) + tmax.getHeight(small) - tmax.getLine(small); + } + } + + + @Override + public int getLine(boolean small) { + if (parentesiIniziale && variables.length == 1) { + return this.variables[0].getLine(small); + } else { + Funzione tl = null; + for (Funzione t : variables) { + if (tl == null || t.getLine(small) >= tl.getLine(small)) { + tl = t; + } + } + if (tl == null) return Utils.getFontHeight(small)/2; + return tl.getLine(small); + } + } + +} diff --git a/src/org/warpgate/pi/calculator/Potenza.java b/src/org/warpgate/pi/calculator/Potenza.java index 34b62d9a..171bc0f8 100644 --- a/src/org/warpgate/pi/calculator/Potenza.java +++ b/src/org/warpgate/pi/calculator/Potenza.java @@ -1,18 +1,46 @@ -package org.warpgate.pi.calculator; - -public class Potenza extends FunzioneDueValori { - - public Potenza(Funzione value1, Funzione value2) { - super(value1, value2); - } - - @Override - public String simbolo() { - return Simboli.POTENZA; - } - - @Override - public Termine calcola() throws NumberFormatException, Errore { - return getVariable1().calcola().pow(getVariable2().calcola()); - } -} +package org.warpgate.pi.calculator; + +import org.warp.engine.Display; + +public class Potenza extends FunzioneDueValori { + + public Potenza(Funzione value1, Funzione value2) { + super(value1, value2); + } + + @Override + public String simbolo() { + return Simboli.POTENZA; + } + + @Override + public Termine calcola() throws NumberFormatException, Errore { + return getVariable1().calcola().pow(getVariable2().calcola()); + } + + @Override + public void draw(int x, int y, Display g, boolean small) { + int dx = 0; + variable1.draw(dx+x, getHeight(small)-variable1.getHeight(small)+y, g, small); + dx+=variable1.getWidth()+1; + variable2.draw(dx+x, y, g, small); + } + + @Override + public int getHeight(boolean small) { + return variable1.getHeight(small)+variable2.getHeight(true)-4; + } + + @Override + public int getLine(boolean small) { + return variable2.getHeight(true)-4+variable1.getLine(small); + } + + @Override + public int getWidth() { + int w1 = getVariable1().getWidth(); + int w2 = getVariable2().getWidth(); + + return w1+1+w2; + } +} diff --git a/src/org/warpgate/pi/calculator/Radice.java b/src/org/warpgate/pi/calculator/Radice.java index 45ace1f8..8dd40e3d 100644 --- a/src/org/warpgate/pi/calculator/Radice.java +++ b/src/org/warpgate/pi/calculator/Radice.java @@ -1,22 +1,41 @@ -package org.warpgate.pi.calculator; - -import org.nevec.rjm.BigSurdVec; - -public class Radice extends FunzioneDueValori { - - public Radice(Funzione value1, Funzione value2) { - super(value1, value2); - } - - @Override - public String simbolo() { - return Simboli.NTH_ROOT; - } - - @Override - public Termine calcola() throws NumberFormatException, Errore { - Termine exponent = new Termine(BigSurdVec.ONE); - exponent = exponent.divide(getVariable1().calcola()); - return getVariable2().calcola().pow(exponent); - } -} +package org.warpgate.pi.calculator; + +import org.nevec.rjm.NumeroAvanzatoVec; +import org.warp.engine.Display; + +public class Radice extends FunzioneDueValori { + + public Radice(Funzione value1, Funzione value2) { + super(value1, value2); + } + + @Override + public String simbolo() { + return Simboli.NTH_ROOT; + } + + @Override + public Termine calcola() throws NumberFormatException, Errore { + Termine exponent = new Termine(NumeroAvanzatoVec.ONE); + exponent = exponent.divide(getVariable1().calcola()); + return getVariable2().calcola().pow(exponent); + } + + @Override + public void draw(int x, int y, Display g, boolean small) { + // TODO Auto-generated method stub + + } + + @Override + public int getWidth() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getHeight(boolean small) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/src/org/warpgate/pi/calculator/RadiceQuadrata.java b/src/org/warpgate/pi/calculator/RadiceQuadrata.java index 32b1de55..5145e14e 100644 --- a/src/org/warpgate/pi/calculator/RadiceQuadrata.java +++ b/src/org/warpgate/pi/calculator/RadiceQuadrata.java @@ -1,20 +1,46 @@ -package org.warpgate.pi.calculator; - -import org.nevec.rjm.Rational; - -public class RadiceQuadrata extends FunzioneSingola { - - public RadiceQuadrata(Funzione value) { - super(value); - } - - @Override - public String simbolo() { - return Simboli.SQUARE_ROOT; - } - - @Override - public Termine calcola() throws NumberFormatException, Errore { - return getVariable().calcola().pow(new Termine(Rational.ONE.divide(new Rational(2,1)))); - } -} +package org.warpgate.pi.calculator; + +import org.nevec.rjm.NumeroAvanzatoVec; +import org.nevec.rjm.Rational; +import org.warp.engine.Display; + +public class RadiceQuadrata extends FunzioneAnteriore { + + public RadiceQuadrata(Funzione value) { + super(value); + } + + @Override + public String simbolo() { + return Simboli.SQUARE_ROOT; + } + + @Override + public Termine calcola() throws NumberFormatException, Errore { + Termine result = getVariable().calcola().pow(new Termine(new Rational(1,2))); + return result; + } + + + @Override + public void draw(int x, int y, Display g, boolean small) { + Utils.writeSquareRoot(g, getVariable(), x, y, small); + } + + @Override + public int getWidth() { + return 5+getVariable().getWidth()+2; + } + + @Override + public int getHeight(boolean small) { + int h1 = getVariable().getHeight(small)+2; + return h1; + } + + @Override + public int getLine(boolean small) { + int h1 = getVariable().getLine(small)+2; + return h1; + } +} diff --git a/src/org/warpgate/pi/calculator/Simboli.java b/src/org/warpgate/pi/calculator/Simboli.java index 0d241d8a..403b225d 100644 --- a/src/org/warpgate/pi/calculator/Simboli.java +++ b/src/org/warpgate/pi/calculator/Simboli.java @@ -1,34 +1,43 @@ -package org.warpgate.pi.calculator; - -import static org.warpgate.pi.calculator.Utils.concat; - -public class Simboli { - public static final String SUM = "+"; - public static final String MULTIPLICATION = "*"; - public static final String DIVISION = "/"; - public static final String NTH_ROOT = "√"; - public static final String SQUARE_ROOT = "Ⓐ"; - public static final String PARENTHESIS_OPEN = "("; - public static final String PARENTHESIS_CLOSE = ")"; - public static final String POTENZA = "^"; - - public static final String[] funzioni() { - return concat(funzioniNSN(), funzioniSN()); - } - public static final String[] funzioniNSN() { - return new String[]{NTH_ROOT, POTENZA}; - } - public static final String[] funzioniSN() { - return new String[]{SQUARE_ROOT}; - } - public static final String[] segni(boolean withMultiplication) { - String[] ret = new String[]{SUM, DIVISION}; - if (withMultiplication) { - ret = Utils.add(ret, MULTIPLICATION); - } - return ret; - } - public static final String[] parentesi() { - return new String[]{PARENTHESIS_OPEN, PARENTHESIS_CLOSE}; - } -} +package org.warpgate.pi.calculator; + +import static org.warpgate.pi.calculator.Utils.concat; + +public class Simboli { + public static final String SUM = "+"; + public static final String SUBTRACTION = "-"; + public static final String MULTIPLICATION = "*"; + public static final String DIVISION = "/"; + public static final String NTH_ROOT = "√"; + public static final String SQUARE_ROOT = "Ⓐ"; + public static final String PARENTHESIS_OPEN = "("; + public static final String PARENTHESIS_CLOSE = ")"; + public static final String POTENZA = "Ⓑ"; + public static final String EQUATION = "="; + public static final String SYSTEM = "{"; + + public static final String[] funzioni() { + return concat(funzioniNSN(), funzioniSN()); + } + public static final String[] funzioniNSN() { + return new String[]{NTH_ROOT, POTENZA}; + } + public static final String[] funzioniSN() { + return new String[]{SQUARE_ROOT}; + } + public static final String[] segni(boolean withMultiplication) { + String[] ret = new String[]{SUM, DIVISION}; + if (withMultiplication) { + ret = Utils.add(ret, MULTIPLICATION); + } + return ret; + } + public static final String[] parentesi() { + return new String[]{PARENTHESIS_OPEN, PARENTHESIS_CLOSE}; + } + public static String[] incognite() { + return new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; + } + public static String[] sintassiGenerale() { + return new String[]{SYSTEM, EQUATION}; + } +} diff --git a/src/org/warpgate/pi/calculator/Somma.java b/src/org/warpgate/pi/calculator/Somma.java index 89e0009a..91841d27 100644 --- a/src/org/warpgate/pi/calculator/Somma.java +++ b/src/org/warpgate/pi/calculator/Somma.java @@ -1,19 +1,61 @@ -package org.warpgate.pi.calculator; - -public class Somma extends FunzioneDueValori { - - public Somma(Funzione value1, Funzione value2) { - super(value1, value2); - } - - @Override - public String simbolo() { - return Simboli.SUM; - } - - @Override - public Termine calcola() throws Errore { - return getVariable1().calcola().add(getVariable2().calcola()); - } - -} +package org.warpgate.pi.calculator; + +import java.awt.Color; +import java.math.BigInteger; + +import org.nevec.rjm.NumeroAvanzatoVec; +import org.warp.engine.Display; + +public class Somma extends FunzioneDueValori { + + public Somma(Funzione value1, Funzione value2) { + super(value1, value2); + } + + @Override + public String simbolo() { + return Simboli.SUM; + } + + @Override + public Termine calcola() throws Errore { + Termine val1 = getVariable1().calcola(); + Termine val2 = getVariable2().calcola(); + Termine result = val1.add(val2); + return result; + } + + + @Override + public void draw(int x, int y, Display g, boolean small) { + int ln = getLine(small); + int dx = 0; + variable1.draw(dx+x, ln-variable1.getLine(small)+y, g, small); + dx+=variable1.getWidth()+1; + try { + NumeroAvanzatoVec tm = variable2.calcola().getTerm(); + + Utils.writeLetter(g, simbolo(), dx+x, ln-Utils.getFontHeight(small)/2+y, small); + dx+=Utils.getPlainTextWidth(simbolo()); + dx+=1; + + } catch (Errore e) { + e.printStackTrace(); + } + variable2.draw(dx+x, ln-variable2.getLine(small)+y, g, small); + } + + @Override + public int getWidth() { + int dx = 0; + dx+=variable1.getWidth()+1; + try { + NumeroAvanzatoVec tm = variable2.calcola().getTerm(); + dx+=Utils.getPlainTextWidth(simbolo()); + dx+=1; + } catch (Errore e) { + e.printStackTrace(); + } + return dx+=variable2.getWidth(); + } +} diff --git a/src/org/warpgate/pi/calculator/Termine.java b/src/org/warpgate/pi/calculator/Termine.java index 3d38c4b5..5590de99 100644 --- a/src/org/warpgate/pi/calculator/Termine.java +++ b/src/org/warpgate/pi/calculator/Termine.java @@ -1,143 +1,378 @@ -package org.warpgate.pi.calculator; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.MathContext; -import java.util.ArrayList; - -import org.nevec.rjm.BigDecimalMath; -import org.nevec.rjm.BigSurd; -import org.nevec.rjm.BigSurdVec; -import org.nevec.rjm.Rational; - -public class Termine implements Funzione { - - protected BigSurdVec term = BigSurdVec.ZERO; - protected ArrayList variables = new ArrayList(); - - public Termine(BigSurdVec val) { - term = val; - } - - public Termine(String s) { - term = new BigSurdVec(new BigSurd(Utils.getRational(s), Rational.ONE)); - } - - public Termine(Rational r) { - term = new BigSurdVec(new BigSurd(r, Rational.ONE)); - } - - public Termine(BigInteger r) { - term = new BigSurdVec(new BigSurd(new Rational(r, BigInteger.ONE), Rational.ONE)); - } - - public Termine(BigDecimal r) { - term = new BigSurdVec(new BigSurd(Utils.getRational(r), Rational.ONE)); - } - - public BigSurdVec getTerm() { - return term; - } - - public void setTerm(BigSurdVec val) { - term = val; - } - - public ArrayList getVariables() { - return variables; - } - - public void setVariables(ArrayList variables) { - this.variables = variables; - } - - @Override - public Termine calcola() { - return this; - } - - @Override - public String simbolo() { - return null; - } - - public Termine add(Termine f) throws Errore { - Termine ret = new Termine(getTerm().add(f.getTerm())); - ret.setVariables(getVariables()); - if (f.getVariables().size() > 0) { - System.err.println("Moltiplicazioni con variabili non implementato"); - throw new Errore(Errori.NOT_IMPLEMENTED); - } - return ret; - } - - public Termine multiply(Termine f) throws Errore { - Termine ret = new Termine(getTerm().multiply(f.getTerm())); - ret.setVariables(getVariables()); - if (f.getVariables().size() > 0) { - System.err.println("Moltiplicazioni con variabili non implementato"); - throw new Errore(Errori.NOT_IMPLEMENTED); - } - return ret; - } - - public Termine divide(Termine f) throws Errore { - Termine ret = new Termine(getTerm().divide(f.getTerm())); - ret.setVariables(getVariables()); - if (f.getVariables().size() > 0) { - System.err.println("Divisioni con variabili non implementato"); - throw new Errore(Errori.NOT_IMPLEMENTED); - } - return ret; - } - - public Termine pow(Termine f) throws Errore { - Termine ret = new Termine(BigSurdVec.ONE); - if (f.getTerm().isBigInteger()) { - for (BigInteger i = BigInteger.ZERO; i.compareTo(f.getTerm().toBigInteger()) < 0; i = i.add(BigInteger.ONE)) { - ret = ret.multiply(new Termine(getTerm())); - ret.setVariables(getVariables()); - if (f.getVariables().size() > 0) { - System.err.println("Potenze con variabili non implementato"); - throw new Errore(Errori.NOT_IMPLEMENTED); - } - } - } else if (getTerm().isRational() && f.getTerm().isRational() && f.getTerm().toRational().denom().compareTo(BigInteger.ONE) == 0) { - ret = new Termine(getTerm().toRational().pow(f.getTerm().toRational())); - ret.setVariables(getVariables()); - if (f.getVariables().size() > 0) { - System.err.println("Potenze con variabili non implementato"); - throw new Errore(Errori.NOT_IMPLEMENTED); - } - } else if (getTerm().isRational() && f.getTerm().isRational() && f.getTerm().toRational().compareTo(Rational.HALF) == 0) { - //Rational originalExponent = f.getTerm().toRational(); - //Rational rootExponent = new Rational(originalExponent.denom(), originalExponent.numer()); - Rational numberToRoot = getTerm().toRational(); - ret = new Termine(new BigSurdVec(new BigSurd(Rational.ONE, numberToRoot))); - ret.setVariables(getVariables()); - if (f.getVariables().size() > 0) { - System.err.println("Potenze con variabili non implementato"); - throw new Errore(Errori.NOT_IMPLEMENTED); - } - } else { - ret = new Termine(BigDecimalMath.pow(getTerm().BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)), f.getTerm().BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)))); - ret.setVariables(getVariables()); - if (f.getVariables().size() > 0) { - System.err.println("Potenze con variabili non implementato"); - throw new Errore(Errori.NOT_IMPLEMENTED); - } - } - return ret; - } - - @Override - public String toString() { - if (getTerm().isBigInteger()) { - return getTerm().toBigInteger().toString(); - } else if (getTerm().isRational()) { - return getTerm().toRational().toString(); - } else { - return getTerm().toFancyString(); - } - } -} +package org.warpgate.pi.calculator; + +import java.awt.Color; +import java.awt.Graphics; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.util.ArrayList; + +import org.nevec.rjm.BigDecimalMath; +import org.nevec.rjm.NumeroAvanzato; +import org.nevec.rjm.NumeroAvanzatoVec; +import org.nevec.rjm.Rational; +import org.warp.engine.Display; + +import com.rits.cloning.Cloner; + +public class Termine implements Funzione { + + protected NumeroAvanzatoVec term = NumeroAvanzatoVec.ZERO; + + public Termine(NumeroAvanzatoVec val) { + term = val; + } + + public Termine(String s) { + term = new NumeroAvanzatoVec(new NumeroAvanzato(Utils.getRational(s), Rational.ONE)); + } + + public Termine(Rational r) { + term = new NumeroAvanzatoVec(new NumeroAvanzato(r, Rational.ONE)); + } + + public Termine(BigInteger r) { + term = new NumeroAvanzatoVec(new NumeroAvanzato(new Rational(r, BigInteger.ONE), Rational.ONE)); + } + + public Termine(BigDecimal r) { + term = new NumeroAvanzatoVec(new NumeroAvanzato(Utils.getRational(r), Rational.ONE)); + } + + public Termine(NumeroAvanzato numeroAvanzato) { + term = new NumeroAvanzatoVec(numeroAvanzato); + } + + public NumeroAvanzatoVec getTerm() { + return term; + } + + public void setTerm(NumeroAvanzatoVec val) { + term = val; + } + + @Override + public Termine calcola() { + return this; + } + + @Override + public String simbolo() { + return toString(); + } + + public Termine add(Termine f) throws Errore { + Termine ret = new Termine(getTerm().add(f.getTerm())); + return ret; + } + + public Termine multiply(Termine f) throws Errore { + Termine ret = new Termine(getTerm().multiply(f.getTerm())); + return ret; + } + + public Termine divide(Termine f) throws Errore { + Termine ret = new Termine(getTerm().divide(f.getTerm())); + return ret; + } + + public Termine pow(Termine f) throws Errore { + Termine ret = new Termine(NumeroAvanzatoVec.ONE); + if (f.getTerm().isBigInteger(true)) { + for (BigInteger i = BigInteger.ZERO; i.compareTo(f.getTerm().toBigInteger(true)) < 0; i = i.add(BigInteger.ONE)) { + ret = ret.multiply(new Termine(getTerm())); + } + } else if (getTerm().isRational(true) && f.getTerm().isRational(false) && f.getTerm().toRational(false).compareTo(Rational.HALF) == 0) { + //Rational originalExponent = f.getTerm().toRational(); + //Rational rootExponent = new Rational(originalExponent.denom(), originalExponent.numer()); + Rational numberToRoot = getTerm().toRational(true); + NumeroAvanzato na = new NumeroAvanzato(Rational.ONE, numberToRoot); + na = na.setIncognitex(getTerm().toNumeroAvanzato().getIncognitey().multiply(getTerm().toNumeroAvanzato().getIncognitez())); + na = na.setIncognitey(new Incognite()); + na = na.setIncognitez(getTerm().toNumeroAvanzato().getIncognitez()); + ret = new Termine(na); + } else { + ret = new Termine(BigDecimalMath.pow(getTerm().BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)), f.getTerm().BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)))); + } + return ret; + } + + @Override + public String toString() { + return getTerm().toFancyString(); + } + + public void draw(int x, int y, Display g, boolean small, boolean drawMinus) { + boolean beforedrawminus = this.drawMinus; + this.drawMinus = drawMinus; + draw(x, y, g, small); + this.drawMinus = beforedrawminus; + } + + private boolean drawMinus = true; + + @Override + public void draw(int x, int y, Display g, boolean small) { + if (getTerm().isBigInteger(false)) { + String t = toString(); + int w1 = Utils.getPlainTextWidth(t); + int h1 = Utils.getFontHeight(small); + + if (t.startsWith("-")) { + if (drawMinus) { + + } else { + int minusw = Utils.getPlainTextWidth("-"); + int minush = Utils.getFontHeight(small); + t = t.substring(1); + } + } + Utils.writeLetter(g, t, x, y, small); + } else if (getTerm().isRational(false)) { + small = true; + Rational r = getTerm().toRational(false); + boolean minus = false; + int minusw = 0; + int minush = 0; + String numerator = r.numer().toString(); + if (numerator.startsWith("-")) { + minus = true; + numerator = numerator.substring(1); + } + int w1 = Utils.getPlainTextWidth(numerator); + int h1 = Utils.getFontHeight(small); + int w2 = Utils.getPlainTextWidth(r.denom().toString()); + int h2 = Utils.getFontHeight(small); + int maxw; + if (w1 > w2) { + maxw = 1+w1+1; + } else { + maxw = 1+w2+1; + } + if (minus) { + if (drawMinus) { + minusw = Utils.getPlainTextWidth("-"); + minush = Utils.getFontHeight(small); + maxw += minusw; + Utils.writeLetter(g, "-", x, y+h1+1+1-(minush/2), small); + } + } + Utils.writeLetter(g, numerator, (int)(x+minusw+1+((double)(maxw-w1))/2d), y, small); + Utils.writeLetter(g, r.denom().toString(), (int)(x+minusw+1+((double)(maxw-w2))/2d), y+h1+1+1+1, small); + g.setColor(Color.BLACK); + g.fillRect(x+minusw+1, y+h1+1, maxw, 1); + } else if (getTerm().toFancyString().contains("/")) { + small = true; + String r = getTerm().toFancyString(); + String numer = r.substring(0, r.lastIndexOf("/")); + String denom = r.substring(numer.length()+1, r.length()); + if (numer.startsWith("(") && numer.endsWith(")")) { + numer = numer.substring(1, numer.length()-1); + } + boolean minus = false; + if (numer.startsWith("-")) { + minus = true; + numer = numer.substring(1); + } + int w1 = Utils.getPlainTextWidth(numer.toString()); + int h1 = Utils.getFontHeight(small); + int w2 = Utils.getPlainTextWidth(denom.toString()); + int h2 = Utils.getFontHeight(small); + int maxw; + if (w1 > w2) { + maxw = w1+2; + } else { + maxw = w2+2; + } + int minusw = 0; + int minush = 0; + if (minus) { + if (drawMinus) { + minusw = Utils.getPlainTextWidth("-")+1; + minush = Utils.getFontHeight(small); + maxw += minusw; + Utils.writeLetter(g, "-", x, y+h1+1+1-(minush/2), small); + } + } + Utils.writeLetter(g, numer, (int)(x+minusw+1+((double)(maxw-w1))/2d), y, small); + Utils.writeLetter(g, denom, (int)(x+minusw+1+((double)(maxw-w2))/2d), y+h1+1+1+1, small); + g.setColor(Color.BLACK); + g.fillRect(x+minusw+1, y+h1+1, maxw, 1); + } else { + String r = getTerm().toFancyString(); + int w1 = Utils.getPlainTextWidth(r.toString()); + int h1 = Utils.getFontHeight(small); + + if (r.startsWith("-")) { + if (drawMinus) { + + } else { + int minusw = Utils.getPlainTextWidth("-")+1; + int minush = Utils.getFontHeight(small); + r = r.substring(1); + } + } + + Utils.writeLetter(g, r.toString(), x, y, small); + } + } + + public int getHeight(boolean small, boolean drawMinus) { + boolean beforedrawminus = this.drawMinus; + this.drawMinus = drawMinus; + int h = getHeight(small); + this.drawMinus = beforedrawminus; + return h; + } + + @Override + public int getHeight(boolean small) { + if (getTerm().isBigInteger(false)) { + int h1 = Utils.getFontHeight(small); + return h1; + } else if (getTerm().isRational(false)) { + small = true; + int h1 = Utils.getFontHeight(small); + int h2 = Utils.getFontHeight(small); + return h1+3+h2; + } else if (getTerm().toFancyString().contains("/")) { + small = true; + int h1 = Utils.getFontHeight(small); + int h2 = Utils.getFontHeight(small); + return h1+3+h2; + } else { + int h1 = Utils.getFontHeight(small); + return h1; + } + } + + public int getWidth(boolean drawMinus) { + boolean beforedrawminus = this.drawMinus; + this.drawMinus = drawMinus; + int w = getWidth(); + this.drawMinus = beforedrawminus; + return w; + } + + @Override + public int getWidth() { + if (getTerm().isBigInteger(false)) { + String t = toString(); + if (t.startsWith("-")) { + if (drawMinus) { + + } else { + t = t.substring(1); + } + } + return Utils.getPlainTextWidth(t); + } else if (getTerm().isRational(false)) { + Rational r = getTerm().toRational(false); + boolean minus = false; + String numerator = r.numer().toString(); + if (numerator.startsWith("-")) { + minus = true; + numerator = numerator.substring(1); + } + int w1 = Utils.getPlainTextWidth(numerator); + int w2 = Utils.getPlainTextWidth(r.denom().toString()); + int maxw; + if (w1 > w2) { + maxw = 1+w1+1; + } else { + maxw = 1+w2+1; + } + if (minus) { + if (drawMinus) { + maxw += Utils.getPlainTextWidth("-"); + } + } + return maxw+2; + } else if (getTerm().toFancyString().contains("/")) { + String r = getTerm().toFancyString(); + String numer = r.substring(0, r.lastIndexOf("/")); + String denom = r.substring(numer.length()+1, r.length()); + if (numer.startsWith("(") && numer.endsWith(")")) { + numer = numer.substring(1, numer.length()-1); + } + boolean minus = false; + if (numer.startsWith("-")) { + minus = true; + numer = numer.substring(1); + } + int w1 = Utils.getPlainTextWidth(numer.toString()); + int w2 = Utils.getPlainTextWidth(denom.toString()); + int maxw; + if (w1 > w2) { + maxw = w1+2; + } else { + maxw = w2+2; + } + if (minus) { + if (drawMinus) { + maxw += Utils.getPlainTextWidth("-"); + } + } + return maxw+2; + } else { + String r = getTerm().toFancyString(); + if (r.startsWith("-")) { + if (drawMinus) { + + } else { + r = r.substring(1); + } + } + return Utils.getPlainTextWidth(r.toString()); + } + } + + public boolean soloIncognitaSemplice() { + if (this.getTerm().isBigInteger(true)) { + if (this.getTerm().toBigInteger(true).compareTo(BigInteger.ONE) == 0 && this.getTerm().toNumeroAvanzato().getIncognitey().count() > 0) { + return true; + } + } + return false; + } + + @Override + public int getLine(boolean small) { + if (getTerm().isBigInteger(false)) { + return Utils.getFontHeight(small)/2; + } else if (getTerm().isRational(false)) { + small = true; + int h1 = Utils.getFontHeight(small); + return h1+1; + } else if (getTerm().toFancyString().contains("/")) { + small = true; + int h1 = Utils.getFontHeight(small); + return h1+1; + } else { + int h1 = Utils.getFontHeight(small); + return h1/2; + } + } + + @Override + public Termine clone() { + Cloner cloner = new Cloner(); + return cloner.deepClone(this); + } + + /* + @Override + public void draw(int x, int y, Graphics g) { + } + + @Override + public int getHeight() { + return Utils.getFontHeight(); + } + + @Override + public int getWidth() { + return 6*toString().length()-1; + } + */ +} diff --git a/src/org/warpgate/pi/calculator/Utils.java b/src/org/warpgate/pi/calculator/Utils.java index ab7e77b7..f55f8e77 100644 --- a/src/org/warpgate/pi/calculator/Utils.java +++ b/src/org/warpgate/pi/calculator/Utils.java @@ -1,156 +1,366 @@ -package org.warpgate.pi.calculator; - -import java.io.StringWriter; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.RoundingMode; -import java.util.ArrayList; - -import org.nevec.rjm.BigDecimalMath; -import org.nevec.rjm.Rational; - -public class Utils { - - public static final int scale = 130; - - public static final int scaleMode = BigDecimal.ROUND_HALF_UP; - public static final RoundingMode scaleMode2 = RoundingMode.HALF_UP; - - public static DebugStream debug = new DebugStream(); - - public static boolean debugOn; - - public static final class DebugStream extends StringWriter { - - public void println(String str) { - if (debugOn) { - System.err.println(str); - } - } - int before = 0; - boolean due = false; - - } - - public static boolean isInArray(String ch, String[] a) { - boolean contains = false; - for (String c : a) { - if (c.equals(ch)) { - contains = true; - break; - } - } - return contains; - } - public static String ArrayToRegex(String[] array) { - String regex = null; - for(String symbol : array) { - if (regex != null) { - regex+="|\\"+symbol; - } else { - regex = "\\"+symbol; - } - } - return regex; - } - public static String[] concat(String[] a, String[] b) { - int aLen = a.length; - int bLen = b.length; - String[] c= new String[aLen+bLen]; - System.arraycopy(a, 0, c, 0, aLen); - System.arraycopy(b, 0, c, aLen, bLen); - return c; - } - public static String[] add(String[] a, String b) { - int aLen = a.length; - String[] c= new String[aLen+1]; - System.arraycopy(a, 0, c, 0, aLen); - c[aLen] = b; - return c; - } - - public static boolean ciSonoSoloNumeriESomme(ArrayList fl) { - for (int i = 0; i < fl.size(); i++) { - if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Somma || fl.get(i) instanceof Parentesi)) { - return false; - } - } - return true; - } - - public static boolean ciSonoFunzioniSNnonImpostate(ArrayList fl) { - for (int i = 0; i < fl.size(); i++) { - if (fl.get(i) instanceof FunzioneSingola) { - if (((FunzioneSingola)fl.get(i)).variable == null) { - return true; - } - } - } - return false; - } - - public static boolean ciSonoAltreFunzioni(ArrayList fl) { - for (int i = 0; i < fl.size(); i++) { - if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Somma || fl.get(i) instanceof Parentesi || fl.get(i) instanceof FunzioneSingola || fl.get(i) instanceof Moltiplicazione || fl.get(i) instanceof Divisione)) { - return true; - } - } - return false; - } - - public static Rational getRational(BigDecimal str) { - return getRational(str.toString()); - } - - public static Rational getRational(String str) { - try { - return new Rational(str); - } catch (NumberFormatException ex) { - long bits = Double.doubleToLongBits(Double.parseDouble(str)); - - long sign = bits >>> 63; - long exponent = ((bits >>> 52) ^ (sign << 11)) - 1023; - long fraction = bits << 12; // bits are "reversed" but that's not a problem - - long a = 1L; - long b = 1L; - - for (int i = 63; i >= 12; i--) { - a = a * 2 + ((fraction >>> i) & 1); - b *= 2; - } - - if (exponent > 0) - a *= 1 << exponent; - else - b *= 1 << -exponent; - - if (sign == 1) - a *= -1; - - if (b == 0) { - a = 0; - b = 1; - } - - - return new Rational(new BigInteger(a+""),new BigInteger(b+"")); - } - } - - public static BigDecimal rationalToIrrationalString(Rational r) { - return BigDecimalMath.divideRound(new BigDecimal(r.numer()).setScale(Utils.scale, Utils.scaleMode), new BigDecimal(r.denom()).setScale(Utils.scale, Utils.scaleMode)); - } - public static boolean variabiliUguali(ArrayList variables, ArrayList variables2) { - if (variables.size() != variables2.size()) { - return false; - } else { - for (VariabileEdEsponente v : variables) { - if (!variables2.contains(v)) { - return false; - } - } - return true; - } - } -} +package org.warpgate.pi.calculator; + +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.io.StringWriter; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.math.RoundingMode; +import java.util.ArrayList; + +import org.nevec.rjm.BigDecimalMath; +import org.nevec.rjm.Rational; +import org.warp.engine.Display; +import org.warp.engine.Display.Font; + +public class Utils { + + public static final int scale = 130; + public static final int resultScale = 8; + + public static final int scaleMode = BigDecimal.ROUND_HALF_UP; + public static final RoundingMode scaleMode2 = RoundingMode.HALF_UP; + public static final Font fontBig = new Font("CalcBig", Font.PLAIN, 16); + public static final Font fontSmall = new Font("CalcSmall", Font.PLAIN, 16); + + public static DebugStream debug = new DebugStream(); + + public static boolean debugOn; + + public static final class DebugStream extends StringWriter { + + public void println(String str) { + if (debugOn) { + System.err.println(str); + } + } + int before = 0; + boolean due = false; + + } + + public static boolean isInArray(String ch, String[] a) { + boolean contains = false; + for (String c : a) { + if (c.equals(ch)) { + contains = true; + break; + } + } + return contains; + } + public static String ArrayToRegex(String[] array) { + String regex = null; + for(String symbol : array) { + if (regex != null) { + regex+="|\\"+symbol; + } else { + regex = "\\"+symbol; + } + } + return regex; + } + public static String[] concat(String[] a, String[] b) { + int aLen = a.length; + int bLen = b.length; + String[] c= new String[aLen+bLen]; + System.arraycopy(a, 0, c, 0, aLen); + System.arraycopy(b, 0, c, aLen, bLen); + return c; + } + public static String[] add(String[] a, String b) { + int aLen = a.length; + String[] c= new String[aLen+1]; + System.arraycopy(a, 0, c, 0, aLen); + c[aLen] = b; + return c; + } + + public static boolean ciSonoSoloFunzioniImpostateSommeEquazioniESistemi(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Somma || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Parentesi)) { + if (fl.get(i) instanceof FunzioneAnteriore) { + if (((FunzioneAnteriore)fl.get(i)).variable == null) { + return false; + } + } else if (fl.get(i) instanceof FunzioneDueValori) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null || ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return false; + } + } else { + return false; + } + } + } + return true; + } + public static boolean ciSonoSoloFunzioniImpostateSommeMoltiplicazioniEquazioniESistemi(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Moltiplicazione || fl.get(i) instanceof Somma || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Parentesi)) { + if (fl.get(i) instanceof FunzioneAnteriore) { + if (((FunzioneAnteriore)fl.get(i)).variable == null) { + return false; + } + } else if (fl.get(i) instanceof FunzioneDueValori) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null || ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return false; + } + } else { + return false; + } + } + } + return true; + } + + public static boolean ciSonoSoloFunzioniImpostateEquazioniESistemi(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Parentesi)) { + if (fl.get(i) instanceof FunzioneAnteriore) { + if (((FunzioneAnteriore)fl.get(i)).variable == null) { + return false; + } + } else if (fl.get(i) instanceof FunzioneDueValori) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null || ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return false; + } + } else { + return false; + } + } + } + return true; + } + + public static boolean ciSonoSoloFunzioniImpostateESistemi(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Parentesi)) { + if (fl.get(i) instanceof FunzioneAnteriore) { + if (((FunzioneAnteriore)fl.get(i)).variable == null) { + return false; + } + } else if (fl.get(i) instanceof FunzioneDueValori) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null || ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return false; + } + } else { + return false; + } + } + } + return true; + } + + public static boolean ciSonoFunzioniSNnonImpostate(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i) instanceof FunzioneAnteriore && !(fl.get(i) instanceof ParteSistema)) { + if (((FunzioneAnteriore)fl.get(i)).variable == null) { + return true; + } + } + } + return false; + } + + public static boolean ciSonoFunzioniNSNnonImpostate(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i) instanceof FunzioneDueValori && !(fl.get(i) instanceof Equazione) && !(fl.get(i) instanceof Somma) && !(fl.get(i) instanceof Sottrazione) && !(fl.get(i) instanceof Moltiplicazione) && !(fl.get(i) instanceof Divisione)) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null && ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return true; + } + } + } + return false; + } + + public static boolean ciSonoMoltiplicazioniNonImpostate(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i) instanceof Moltiplicazione || fl.get(i) instanceof Divisione) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null && ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return true; + } + } + } + return false; + } + + public static boolean ciSonoSommeNonImpostate(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i) instanceof Somma) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null && ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return true; + } + } + } + return false; + } + + public static boolean ciSonoEquazioniNonImpostate(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i) instanceof Equazione) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null && ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return true; + } + } + } + return false; + } + + public static boolean ciSonoSistemiNonImpostati(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i) instanceof ParteSistema) { + if (((ParteSistema)fl.get(i)).variable == null) { + return true; + } + } + } + return false; + } + + public static boolean ciSonoAltreFunzioniImpostate(ArrayList fl) { + for (int i = 0; i < fl.size(); i++) { + if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Somma || fl.get(i) instanceof Parentesi || fl.get(i) instanceof FunzioneAnteriore || fl.get(i) instanceof Moltiplicazione || fl.get(i) instanceof Divisione)) { + if (fl.get(i) instanceof FunzioneAnteriore) { + if (((FunzioneAnteriore)fl.get(i)).variable == null) { + return true; + } + } else if (fl.get(i) instanceof FunzioneDueValori) { + if (((FunzioneDueValori)fl.get(i)).variable1 == null || ((FunzioneDueValori)fl.get(i)).variable2 == null) { + return true; + } + } else { + return true; + } + } + } + return false; + } + + public static Rational getRational(BigDecimal str) { + return getRational(str.toString()); + } + + public static Rational getRational(String str) { + try { + return new Rational(str); + } catch (NumberFormatException ex) { + if (new BigDecimal(str).compareTo(new BigDecimal(Double.MAX_VALUE)) < 0 && new BigDecimal(str).compareTo(new BigDecimal(Double.MIN_VALUE)) > 0) { + if (str.equals("-")) { + str = "-1"; + } + long bits = Double.doubleToLongBits(Double.parseDouble(str)); + + long sign = bits >>> 63; + long exponent = ((bits >>> 52) ^ (sign << 11)) - 1023; + long fraction = bits << 12; // bits are "reversed" but that's not a problem + + long a = 1L; + long b = 1L; + + for (int i = 63; i >= 12; i--) { + a = a * 2 + ((fraction >>> i) & 1); + b *= 2; + } + + if (exponent > 0) + a *= 1 << exponent; + else + b *= 1 << -exponent; + + if (sign == 1) + a *= -1; + + if (b == 0) { + a = 0; + b = 1; + } + + return new Rational(new BigInteger(a+""),new BigInteger(b+"")); + } else { + BigDecimal original = new BigDecimal(str); + + BigInteger numerator = original.unscaledValue(); + + BigInteger denominator = BigDecimalMath.pow(BigDecimal.TEN, new BigDecimal(original.scale())).toBigIntegerExact(); + + return new Rational(numerator, denominator); + } + } + } + + public static BigDecimal rationalToIrrationalString(Rational r) { + return BigDecimalMath.divideRound(new BigDecimal(r.numer()).setScale(Utils.scale, Utils.scaleMode), new BigDecimal(r.denom()).setScale(Utils.scale, Utils.scaleMode)); + } + public static boolean variabiliUguali(ArrayList variables, ArrayList variables2) { + if (variables.size() != variables2.size()) { + return false; + } else { + for (Incognita v : variables) { + if (!variables2.contains(v)) { + return false; + } + } + return true; + } + } + + public static void writeLetter(Display d, String text, int x, int y, boolean small) { + if (small) { + d.setFont(fontSmall); + } else { + d.setFont(fontBig); + } + d.setColor(Color.BLACK); + d.drawString(text, x, y+getFontHeight(small)); + } + + public static void writeSquareRoot(Display g, Funzione var, int x, int y, boolean small) { + if (small) { + g.setFont(fontSmall); + } else { + g.setFont(fontBig); + } + g.setColor(Color.BLACK); + int w1 = var.getWidth(); + int h1 = var.getHeight(small); + int wsegno = 5; + int hsegno = h1+2; + + var.draw(x+wsegno, y+(hsegno-h1), g, small); + + g.draw45Line(x, y+hsegno-3, x+2, y+hsegno-1, false); + g.drawOrthoLine(x+2, y+(hsegno-1)/2+1, x+2, y+hsegno-1); + g.drawOrthoLine(x+3, y, x+3, y+(hsegno-1)/2); + g.drawOrthoLine(x+3, y, x+3+1+w1+2, y); + } + + public static final int getPlainTextWidth(String text) { + Graphics graphics = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getGraphics(); + // get metrics from the graphics + FontMetrics metrics = graphics.getFontMetrics(fontBig.getFontAwt()); + // get the advance of my text in this font + // and render context + int adv = metrics.stringWidth(text); + // calculate the size of a box to hold the + // text with some padding. + if (adv > 0) { + adv-=1; + } + return adv; + } + + public static final int getFontHeight() { + return getFontHeight(false); + } + + public static final int getFontHeight(boolean small) { + if (small) { + return 6; + } else { + return 9; + } + } +} diff --git a/src/org/warpgate/pi/calculator/VariabileEdEsponente.java b/src/org/warpgate/pi/calculator/VariabileEdEsponente.java deleted file mode 100644 index ec56690b..00000000 --- a/src/org/warpgate/pi/calculator/VariabileEdEsponente.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.warpgate.pi.calculator; - -import java.math.BigInteger; - -public class VariabileEdEsponente { - public char simbolo = 'X'; - public BigInteger esponente = BigInteger.ONE; - - public VariabileEdEsponente(char simbolo, BigInteger esponente) { - this.simbolo = simbolo; - this.esponente = esponente; - } - - @Override - public boolean equals(Object o) { - if (o instanceof VariabileEdEsponente) { - if (this.simbolo == ((VariabileEdEsponente) o).simbolo) { - if (this.esponente == ((VariabileEdEsponente) o).esponente) { - return true; - } - } - } - return false; - } -}