Is there a commonly used rational numbers library in Java?

前端 未结 5 963
日久生厌
日久生厌 2020-11-27 05:55

I\'m looking for a Java library which represents fractions (rational numbers). For example, if I want to store the fraction 1/3 then it will not be saved as

5条回答
  •  一整个雨季
    2020-11-27 06:29

    Edit from Future: Please use Apache Commons or any other supported library. This was just a sample demonstration.

    I implemented a small class that can be used for that purposes, maybe it can be useful for you as well, use with caution.

    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 nominators = new ArrayList();
        public ArrayList denominators = new ArrayList();
    
        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 nominatorList,
                ArrayList 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 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 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);
        }
    
    
    
    }
    

提交回复
热议问题