functions - math.ceil java
¿Hay una biblioteca de números racionales comúnmente utilizada en Java? (5)
Estoy buscando una biblioteca Java que represente fracciones (números racionales). Por ejemplo, si quiero almacenar la fracción 1/3
, no se guardará como 0.33333
que perderá su precisión.
Aquí hay algunas de las funcionalidades que espero encontrar en una biblioteca de este tipo:
-
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()
Puedo implementar una biblioteca de este tipo por mi cuenta, aunque me preguntaba si ya existe algo similar.
EDITAR: También sería bueno si la biblioteca implementa (además de lo anterior) algunos algoritmos de teoría de números, como getEgyptianFractionsSum()
etc.
¿Te satisface Apache Commons Math ?
Implementé una pequeña clase que se puede usar para esos fines, tal vez también pueda ser útil para ti, usar con precaución.
import java.util.ArrayList;
public class RationalNumber {
/**
*
* @author Suat KARAKUSOGLU
* @email [email protected]
* 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);
}
}
La biblioteca JScience
incluye la clase org.jscience.mathematics.number.Rational
. Además de las fábricas, accesos y operaciones habituales, se pueden construir otras entidades útiles, como Polynomial<Rational>
, Vector<Rational>
y Matrix<Rational>
.
Como ejemplo, una función para obtener el mínimo común denominador de una colección de fracciones podría verse así:
private static LargeInteger lcd(Collection<Rational> fractions) {
Rational sum = Rational.ZERO;
for (Rational rational : fractions) {
sum = sum.plus(rational);
}
return sum.getDivisor();
}
La siguiente declaración imprime 6
:
System.out.println(lcd(Arrays.asList(
Rational.valueOf(1, 2), Rational.valueOf(1, 3))));
La biblioteca Apfloat tiene muchas características geniales, rendimiento, precisión, etc. Definitivamente es un mejor BigDecimal que para ser justo funciona pero es bastante simple y ofrece poca funcionalidad.
http://www.apfloat.org/apfloat_java/
Contenido:
Configuración de Classpath Primer ejemplo Construcción de Apfloats Advertencias de constructor Double y float Apfloats son inmutables Precision Output Funciones matemáticas avanzadas Enteros Números complejos Números racionales Uso de algún otro radix que no sea 10 Igualdad y comparación Formateo
No estoy seguro de cuán comúnmente usado es, pero los paquetes apfloat (Java y C ++) contienen una clase para la aritmética racional .