Implemented MCD

This commit is contained in:
Andrea Cavalli 2017-07-02 23:09:44 +02:00
parent 0277af9eca
commit d02f5c7db8
4 changed files with 106 additions and 4 deletions

View File

@ -138,7 +138,8 @@ public class BigIntegerMath {
}
/**
* Compute the list of positive divisors.
* Compute the list of positive divisors.<br>
* <b>Deprecated: This function is extremely slow and inefficient!</b>
*
* @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<BigInteger> divisors(final BigInteger n) {
return (new Ifactor(n.abs())).divisors();
}

View File

@ -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<BigInteger> empty = null;
LinkedList<BigInteger> 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);
}
}

View File

@ -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<BigInteger> factors1 = ((Number) variable1).getFactors();
LinkedList<BigInteger> 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<BigInteger> factors1 = ((Number) variable1).getFactors();
LinkedList<BigInteger> 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;
}

View File

@ -194,7 +194,11 @@ public class Number implements Function {
}
return false;
}
/**
* @author programmingpraxis
* @return
*/
public LinkedList<BigInteger> getFactors() {
BigInteger n = getTerm().toBigIntegerExact();
final BigInteger two = BigInteger.valueOf(2);