我正在寻找一个代表分数(有理数)的Java库。例如,如果我想存储分数1/3
,那么它将不会保存为0.33333
,这将失去其准确性。
以下是我希望在这样的库中找到的一些功能:
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()
我可以自己实现这样一个库,不过我想知道类似的东西是否已经存在。
编辑:如果图书馆实现了(除上述之外)一些数论算法,例如getEgyptianFractionsSum()
等,也会很好。
答案 0 :(得分:16)
Apache Commons Math适合你吗?
答案 1 :(得分:13)
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))));
答案 2 :(得分:1)
我不确定它是多么常用,但apfloat包(Java和C ++)包含a class for rational arithmetic。
答案 3 :(得分:1)
Apfloat库具有许多强大的功能,性能,准确性等。它绝对是一个更好的BigDecimal,它是公平的,但非常简单并且功能很少。
http://www.apfloat.org/apfloat_java/
内容:
类路径设置 第一个例子 建造Apfloats Double和float构造函数警告 Apfloats是不可改变的 精确 产量 高级数学函数 整型 复数 有理数 使用其他一些基数比10 平等和比较 格式化
答案 4 :(得分:1)
我实现了一个可用于此目的的小类,也许它对你有用,请谨慎使用。
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("a-b ="+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
* a-b =-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);
}
}