Java中有一个常用的有理数字库吗?

我正在寻找代表分数(有理数)的Java库。 例如,如果我想存储分数1/3那么它不会被保存为0.33333 ,这将失去它的准确性。

以下是我期望在这样一个图书馆中find的一些function:

  • getNumerator()
  • getDenominator()
  • add(Rational r1, Rational r2)subtract(Rational r1, Rational r2)multiply(Rational r1, Rational r2)divide(Rational r1, Rational r2)
  • isProper()
  • getCommonDenominator(Collection<Rational> rationals)
  • getSimplified()

我可以自己实现这样一个图书馆,但是我想知道是否有类似的东西已经存在。

编辑:这也将是很好,如果图书馆实施(除了上述)一些数字理论algorithm,如getEgyptianFractionsSum()

JScience库包含org.jscience.mathematics.number.Rational类。 除了通常的工厂,访问器和操作外,还可以构造其他有用的实体,包括Polynomial<Rational>Vector<Rational>Matrix<Rational>

作为一个例子,获得分数集合的最小公分母的函数可能如下所示:

 private static LargeInteger lcd(Collection<Rational> fractions) { Rational sum = Rational.ZERO; for (Rational rational : fractions) { sum = sum.plus(rational); } return sum.getDivisor(); } 

以下语句打印6

 System.out.println(lcd(Arrays.asList( Rational.valueOf(1, 2), Rational.valueOf(1, 3)))); 

Apache Commons Math适合你吗?

我不确定它是多么常用,但是apfloat包(Java和C ++)包含一个用于理性运算的类 。

Apfloat库有很多很棒的function,性能,准确性等等。 它绝对是一个更好的BigDecimal这是公平的作品,但相当简单,并提供一点function。

http://www.apfloat.org/apfloat_java/

内容:

类path设置第一个示例构造Apfloats双精度和浮点构造函数警告Apfloats是不可变的精度输出高级math函数整数复数有理数使用除10之外的其他基数相等和比较格式化

我实现了一个小类,可以用于这个目的,也许它可以对你有用,谨慎使用。

 import java.util.ArrayList; public class RationalNumber { /** * * @author Suat KARAKUSOGLU * @email suatkarakusoglu@gmail.com * This class has 2 kind of constructors * 1. is RationalNumber a=new RationalNumber("3.3"); * RationalNumber a=new RationalNumber("-3.3"); * With this constructor one can enter the decimal number and also specify whether negative or not * * 2. is RationalNumber a=new RationalNumber(3,5); * With this constructor the first value is nominator and second one is denominator. * * The advantage side of this class is, it prevents the fractional errors while dividing * RationalNumber keeps all denominator and nominator values as it is and when the real value is * needed, the calculation occurs at that time. * * Supports multiply,divide,add,subtract operations on RationalNumber classes. * */ /* * Simple Usage: * * RationalNumber a=new RationalNumber("3.3"); * RationalNumber b=new RationalNumber("4.5"); * System.out.println("a ="+a.getStringValue()); * System.out.println("b ="+b.getStringValue()); * System.out.println("ab ="+a.subtract(b).getStringValue()); * System.out.println("a ="+a.getStringValue()); * System.out.println("b ="+b.getStringValue()); * RationalNumber k=a.divide(b); * System.out.println("a/b="+k.getStringValue()); * System.out.println("a/b="+k.getDoubleValue()); * * System out results: * * a =33/10 * b =9/2 * ab =-6/5 * a =33/10 * b =9/2 * a/b=11/15 * a/b=0.7333333333333333 * */ public ArrayList<Long> nominators = new ArrayList<Long>(); public ArrayList<Long> denominators = new ArrayList<Long>(); public RationalNumber(String rationalNumberStringValue) { this(parseRationalNumberStringValue(rationalNumberStringValue)[0], parseRationalNumberStringValue(rationalNumberStringValue)[1]); } private static Long[] parseRationalNumberStringValue( String rationalNumberStringValue) { boolean positive = true; if (rationalNumberStringValue.charAt(0) == '-') { positive = false; rationalNumberStringValue = rationalNumberStringValue.substring(1); } // 0. index is keeping nominator // 1. index is keeping denominator Long[] nominatorDenominator = new Long[2]; nominatorDenominator[0] = 1l; nominatorDenominator[1] = 1l; String[] splittedNumberArr = rationalNumberStringValue.split("\\."); String denominatorStr = splittedNumberArr[1]; for (int i = 0; i < denominatorStr.length(); i++) { nominatorDenominator[1] *= 10; } rationalNumberStringValue = removeCharAt(rationalNumberStringValue, rationalNumberStringValue.indexOf('.')); nominatorDenominator[0] = Long.valueOf(rationalNumberStringValue); if (!positive) { nominatorDenominator[0] *= -1; } return nominatorDenominator; } public static String removeCharAt(String s, int pos) { return s.substring(0, pos) + s.substring(pos + 1); } public RationalNumber(Integer nominator, Integer denominator) { this((long) nominator, (long) denominator); } public RationalNumber(Long nominator, Long denominator) { nominators.add(nominator); denominators.add(denominator); simplify(); } public RationalNumber(ArrayList<Long> nominatorList, ArrayList<Long> denominatorList) { nominators.addAll(nominatorList); denominators.addAll(denominatorList); simplify(); } public String getStringValue() { return getMultipliedValue(this.nominators) + "/" + getMultipliedValue(this.denominators); } public double getDoubleValue() { return (double) getMultipliedValue(this.nominators) / (double) getMultipliedValue(this.denominators); } public RationalNumber multiply(RationalNumber rationalNumberToMultiply) { RationalNumber mulResult = new RationalNumber( rationalNumberToMultiply.nominators, rationalNumberToMultiply.denominators); mulResult.nominators.addAll(this.nominators); mulResult.denominators.addAll(this.denominators); return RationalNumber.simplifyRationalNumber(mulResult); } public RationalNumber divide(RationalNumber rationalNumberToDivide) { RationalNumber divideResult = new RationalNumber( rationalNumberToDivide.nominators, rationalNumberToDivide.denominators); // division means multiplication with reverse values ArrayList<Long> tempLongList = divideResult.nominators; divideResult.nominators = divideResult.denominators; divideResult.denominators = tempLongList; return this.multiply(divideResult); } public RationalNumber add(RationalNumber rationalNumberToAdd) { rationalNumberToAdd = RationalNumber .simplifyRationalNumber(rationalNumberToAdd); return new RationalNumber( (getMultipliedValue(this.nominators) * getMultipliedValue(rationalNumberToAdd.denominators)) + (getMultipliedValue(this.denominators) * getMultipliedValue(rationalNumberToAdd.nominators)), (getMultipliedValue(this.denominators) * getMultipliedValue(rationalNumberToAdd.denominators))); } public RationalNumber subtract(RationalNumber rationalNumberToSubtract) { rationalNumberToSubtract = RationalNumber .simplifyRationalNumber(rationalNumberToSubtract); RationalNumber subtractTempRational = new RationalNumber( rationalNumberToSubtract.nominators, rationalNumberToSubtract.denominators); // Multiply one of its nominators negative value subtractTempRational.nominators.set(0, (subtractTempRational.nominators.get(0) * -1)); // add with its negative value return this.add(subtractTempRational); } private long getMultipliedValue(ArrayList<Long> longList) { Long mulResult = 1l; for (Long tempLong : longList) { mulResult *= tempLong; } return mulResult; } // simplifies original rationalnumber public void simplify() { long tempGcd = 1; long iValue = 1; long jValue = 1; for (int i = 0; i < this.nominators.size(); i++) { iValue = this.nominators.get(i); for (int j = 0; j < this.denominators.size(); j++) { jValue = this.denominators.get(j); tempGcd = gcd(iValue, jValue); this.nominators.set(i, iValue / tempGcd); this.denominators.set(j, jValue / tempGcd); } } } public static RationalNumber simplifyRationalNumber( RationalNumber rationalNumberToSimplify) { long tempGcd = 1; long iValue = 1; long jValue = 1; for (int i = 0; i < rationalNumberToSimplify.nominators.size(); i++) { for (int j = 0; j < rationalNumberToSimplify.denominators.size(); j++) { iValue = rationalNumberToSimplify.nominators.get(i); jValue = rationalNumberToSimplify.denominators.get(j); tempGcd = gcd(iValue, jValue); rationalNumberToSimplify.nominators.set(i, iValue / tempGcd); rationalNumberToSimplify.denominators.set(j, jValue / tempGcd); } } return rationalNumberToSimplify; } // Euclidean algorithm to find greatest common divisor public static long gcd(long a, long b) { a = Math.abs(a); b = Math.abs(b); if (a < b) { long temp = a; a = b; b = temp; } if (b == 0) return a; else return gcd(b, a % b); } public RationalNumber add(int integerToAdd) { RationalNumber tempRationalNumber=new RationalNumber(integerToAdd,1); return this.add(tempRationalNumber); } public RationalNumber subtract(int integerToSubtract) { RationalNumber tempRationalNumber=new RationalNumber(integerToSubtract,1); return this.subtract(tempRationalNumber); } public RationalNumber multiply(int integerToMultiply) { RationalNumber tempRationalNumber=new RationalNumber(integerToMultiply,1); return this.multiply(tempRationalNumber); } public RationalNumber divide(int integerToDivide) { RationalNumber tempRationalNumber=new RationalNumber(integerToDivide,1); return this.divide(tempRationalNumber); } }