diff --git a/src/main/java/org/nevec/rjm/BigIntegerMath.java b/src/main/java/org/nevec/rjm/BigIntegerMath.java index 19a6ef0e..a683c6d9 100755 --- a/src/main/java/org/nevec/rjm/BigIntegerMath.java +++ b/src/main/java/org/nevec/rjm/BigIntegerMath.java @@ -138,7 +138,8 @@ public class BigIntegerMath { } /** - * Compute the list of positive divisors. + * Compute the list of positive divisors.
+ * Deprecated: This function is extremely slow and inefficient! * * @param n * The integer of which the divisors are to be found. @@ -146,6 +147,7 @@ public class BigIntegerMath { * @since 2010-08-27 * @author Richard J. Mathar */ + @Deprecated static public Vector divisors(final BigInteger n) { return (new Ifactor(n.abs())).divisors(); } diff --git a/src/main/java/org/warp/picalculator/Main.java b/src/main/java/org/warp/picalculator/Main.java index 1b1b3108..3a5ae9c8 100755 --- a/src/main/java/org/warp/picalculator/Main.java +++ b/src/main/java/org/warp/picalculator/Main.java @@ -1,9 +1,16 @@ package org.warp.picalculator; +import java.math.BigInteger; +import java.util.LinkedList; +import java.util.Vector; + +import org.nevec.rjm.BigIntegerMath; import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.screens.LoadingScreen; import org.warp.picalculator.gui.screens.Screen; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Number; import com.pi4j.system.SystemInfo.BoardType; import com.pi4j.wiringpi.Gpio; @@ -56,6 +63,69 @@ public class Main { } public static void main(String[] args) throws InterruptedException { + /* + * TEST: Comparing BigIntegerMath.divisors() vs programmingpraxis' Number.getFactors() function + * + long time1; + long time2; + final int max = 10000; + final long HCN = 720720L; + final long LCN = 104911L; + final BigInteger[] bigintegers = new BigInteger[max]; + bigintegers[0] = BigInteger.valueOf(HCN); + for (int i = 0; i < max; i++) { + bigintegers[i] = bigintegers[0]; + } + final Number[] numbers = new Number[max]; + final MathContext mc = new MathContext(); + numbers[0] = new Number(mc, HCN); + for (int i = 0; i < max; i++) { + numbers[i] = numbers[0]; + } + Vector empty = null; + LinkedList empty2 = null; + + time1 = System.currentTimeMillis(); + for(int i = 0; i < max; i++) { + empty = BigIntegerMath.divisors(bigintegers[i]); + } + time2 = System.currentTimeMillis(); + System.out.println("BigIntegerMath HCN: "+(time2-time1)+" ("+empty.toString()+")"); + + + bigintegers[0] = BigInteger.valueOf(LCN); + for (int i = 0; i < max; i++) { + bigintegers[i] = bigintegers[0]; + } + + time1 = System.currentTimeMillis(); + for(int i = 0; i < max; i++) { + empty = BigIntegerMath.divisors(bigintegers[i]); + } + time2 = System.currentTimeMillis(); + System.out.println("BigIntegerMath LCN: "+(time2-time1)+" ("+empty.toString()+")"); + + time1 = System.currentTimeMillis(); + for(int i = 0; i < max; i++) { + empty2 = numbers[i].getFactors(); + } + time2 = System.currentTimeMillis(); + System.out.println("BigIntegerMath HCN: "+(time2-time1)+" ("+empty2.toString()+")"); + + numbers[0] = new Number(mc, LCN); + for (int i = 0; i < max; i++) { + numbers[i] = numbers[0]; + } + time1 = System.currentTimeMillis(); + for(int i = 0; i < max; i++) { + empty2 = numbers[i].getFactors(); + } + time2 = System.currentTimeMillis(); + System.out.println("BigIntegerMath LCN: "+(time2-time1)+" ("+empty2.toString()+")"); + if(true) { + System.exit(0);; + } + */ new Main(args); } } diff --git a/src/main/java/org/warp/picalculator/math/functions/Division.java b/src/main/java/org/warp/picalculator/math/functions/Division.java index ef1788ff..55306112 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Division.java +++ b/src/main/java/org/warp/picalculator/math/functions/Division.java @@ -1,5 +1,9 @@ package org.warp.picalculator.math.functions; +import java.math.BigInteger; +import java.util.LinkedList; + +import org.nevec.rjm.BigIntegerMath; import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockChar; @@ -49,7 +53,15 @@ public class Division extends FunctionOperator { if (variable1 instanceof Number && variable2 instanceof Number) { if (getMathContext().exactMode) { try { - return ((Number) variable1).divide((Number) variable2).isInteger(); + if (((Number) variable1).isInteger() && ((Number) variable2).isInteger()) { + LinkedList factors1 = ((Number) variable1).getFactors(); + LinkedList factors2 = ((Number) variable2).getFactors(); + return factors1.retainAll(factors2); //True If something changed in the factors list by keeping only the intersection of the two factor lists. + } else if (((Number) variable1).divide((Number) variable2).isInteger()) { + return true; + } else { + return false; + } } catch (final Error e) { return false; } @@ -78,7 +90,21 @@ public class Division extends FunctionOperator { } else if (UndefinedRule2.compare(this)) { result = UndefinedRule2.execute(this); } else if (variable1 instanceof Number && variable2 instanceof Number) { - result.add(((Number) variable1).divide((Number) variable2)); + if (getMathContext().exactMode && (((Number) variable1).isInteger() && ((Number) variable2).isInteger())) { + LinkedList factors1 = ((Number) variable1).getFactors(); + LinkedList factors2 = ((Number) variable2).getFactors(); + if(factors1.retainAll(factors2)) { //True If something changed in the factors list by keeping only the intersection of the two factor lists. + BigInteger nmb1 = ((Number) this.getParameter1()).term.toBigIntegerExact(); + BigInteger nmb2 = ((Number) this.getParameter2()).term.toBigIntegerExact(); + for (BigInteger i : factors1) { + nmb1 = nmb1.divide(i); + nmb2 = nmb2.divide(i); + } + result.add(new Division(mathContext, new Number(mathContext, nmb1), new Number(mathContext, nmb2))); + } + } else { + result.add(((Number) variable1).divide((Number) variable2)); + } } return result; } diff --git a/src/main/java/org/warp/picalculator/math/functions/Number.java b/src/main/java/org/warp/picalculator/math/functions/Number.java index 74b1b550..93dd66ca 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Number.java +++ b/src/main/java/org/warp/picalculator/math/functions/Number.java @@ -194,7 +194,11 @@ public class Number implements Function { } return false; } - + + /** + * @author programmingpraxis + * @return + */ public LinkedList getFactors() { BigInteger n = getTerm().toBigIntegerExact(); final BigInteger two = BigInteger.valueOf(2);