Package org.semanticweb.HermiT.datatypes.owlreal

Source Code of org.semanticweb.HermiT.datatypes.owlreal.Numbers

/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory
  
   This file is part of HermiT.

   HermiT is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
  
   HermiT is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.
  
   You should have received a copy of the GNU Lesser General Public License
   along with HermiT.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.semanticweb.HermiT.datatypes.owlreal;

import java.math.BigDecimal;
import java.math.BigInteger;

public class Numbers {
    public static boolean isValidNumber(Number n) {
        return (n instanceof Integer) || (n instanceof Long) || (n instanceof BigInteger) || (n instanceof BigDecimal) || (n instanceof BigRational);
    }
    /**
     * Parses the given string into a Java Number object representing an integer.
     * The Java object is chosen such that .equals() works correctly across all Number-derived objects.
     */
    public static Number parseInteger(String string) throws NumberFormatException {
        try {
            return Integer.parseInt(string);
        }
        catch (NumberFormatException e) {
        }
        try {
            return Long.parseLong(string);
        }
        catch (NumberFormatException e) {
        }
        return new BigInteger(string);
    }
    /**
     * Parses the given string into a Java Number object representing an decimal.
     * The Java object is chosen such that .equals() works correctly across all Number-derived objects.
     */
    public static Number parseDecimal(String string) throws NumberFormatException {
        BigDecimal decimal=new BigDecimal(string);
        try {
            return decimal.intValueExact();
        }
        catch (ArithmeticException e) {
        }
        try {
            return decimal.longValueExact();
        }
        catch (ArithmeticException e) {
        }
        try {
            return decimal.toBigIntegerExact();
        }
        catch (ArithmeticException e) {
        }
        return decimal.stripTrailingZeros();
    }
    /**
     * Parses the given string into a Java Number object representing a rational.
     * The Java object is chosen such that .equals() works correctly across all Number-derived objects.
     */
    public static Number parseRational(String string) throws NumberFormatException {
        int divideIndex=string.indexOf('/');
        if (divideIndex==-1)
            throw new NumberFormatException("The string does not contain /.");
        BigInteger numerator=new BigInteger(string.substring(0,divideIndex));
        BigInteger denominator=new BigInteger(string.substring(divideIndex+1));
        if (denominator.compareTo(BigInteger.ZERO)<=0)
            throw new NumberFormatException("Invalid denumerator of the rational.");
        BigInteger gcd=numerator.gcd(denominator);
        numerator=numerator.divide(gcd);
        denominator=denominator.divide(gcd);
        if (denominator.equals(BigInteger.ONE)) {
            int numeratorBitCount=numerator.bitCount();
            if (numeratorBitCount<=32)
                return numerator.intValue();
            else if (numeratorBitCount<=64)
                return numerator.longValue();
            else
                return numerator;
        }
        try {
            return new BigDecimal(numerator).divide(new BigDecimal(denominator));
        }
        catch (ArithmeticException e) {
        }
        return new BigRational(numerator,denominator);
    }
    public static int compare(Number n1,Number n2) {
        if (n1.equals(n2))
            return 0;
        else if (n1.equals(MinusInfinity.INSTANCE) || n2.equals(PlusInfinity.INSTANCE))
            return -1;
        else if (n1.equals(PlusInfinity.INSTANCE) || n2.equals(MinusInfinity.INSTANCE))
            return 1;
        int typeN1=getNumberType(n1);
        int typeN2=getNumberType(n2);
        int maxType=Math.max(typeN1,typeN2);
        switch (maxType) {
        case 0: {
                int iv1=n1.intValue();
                int iv2=n2.intValue();
                return iv1<iv2 ? -1 : (iv1==iv2 ? 0 : 1);
            }
        case 1: {
                long lv1=n1.longValue();
                long lv2=n2.longValue();
                return lv1<lv2 ? -1 : (lv1==lv2 ? 0 : 1);
            }
        case 2: {
                BigInteger bi1=toBigInteger(n1,typeN1);
                BigInteger bi2=toBigInteger(n2,typeN2);
                return bi1.compareTo(bi2);
            }
        case 3: {
                BigDecimal bd1=toBigDecimal(n1,typeN1);
                BigDecimal bd2=toBigDecimal(n2,typeN2);
                return bd1.compareTo(bd2);
            }
        case 4: {
                BigRational br1=toBigRational(n1,typeN1);
                BigRational br2=toBigRational(n2,typeN2);
                return br1.compareTo(br2);
            }
        default:
            throw new IllegalArgumentException();
        }
    }
    protected static int getNumberType(Number n) {
        if (n instanceof Integer)
            return 0;
        else if (n instanceof Long)
            return 1;
        else if (n instanceof BigInteger)
            return 2;
        else if (n instanceof BigDecimal)
            return 3;
        else if (n instanceof BigRational)
            return 4;
        else
            throw new IllegalArgumentException();
    }
    protected static BigInteger toBigInteger(Number n,int nType) {
        switch (nType) {
        case 0:
        case 1:
            return BigInteger.valueOf(n.longValue());
        case 2:
            return (BigInteger)n;
        default:
            throw new IllegalArgumentException();
        }
    }
    protected static BigDecimal toBigDecimal(Number n,int nType) {
        switch (nType) {
        case 0:
        case 1:
            // We do not strip trailing zeros here! This is OK
            // because these numbers are used only during comparisons.
            return BigDecimal.valueOf(n.longValue());
        case 2:
            // We do not strip trailing zeros here! This is OK
            // because these numbers are used only during comparisons.
            return new BigDecimal((BigInteger)n);
        case 3:
            return (BigDecimal)n;
        default:
            throw new IllegalArgumentException();
        }
    }
    protected static BigRational toBigRational(Number n,int nType) {
        // The resulting rational is not necessary reduced!
        // This means that .equals() and .hashCode() need not
        // work properly. This, however, should not matter,
        // since the resulting object is used only in comparisons.
        switch (nType) {
        case 0:
        case 1:
            return new BigRational(BigInteger.valueOf(n.longValue()),BigInteger.ONE);
        case 2:
            return new BigRational((BigInteger)n,BigInteger.ONE);
        case 3: {
                BigDecimal decimal=(BigDecimal)n;
                // This method assumes that all BigDecimals actually have some decimal digits.
                assert decimal.scale()>0;
                return new BigRational(decimal.unscaledValue(),BigInteger.TEN.pow(decimal.scale()));
            }
        default:
            throw new IllegalArgumentException();
        }
    }
   
    public static enum BoundaryDirection {
        UPPER,LOWER
    }
   
    public static Number getNearestIntegerInBound(Number bound,BoundaryDirection boundaryDirection,boolean boundIsInclusive) {
        switch (getNumberType(bound)) {
        case 0:
            if (boundIsInclusive)
                return bound;
            else if (BoundaryDirection.LOWER.equals(boundaryDirection)) {
                int value=bound.intValue();
                if (value==Integer.MAX_VALUE)
                    return ((long)value)+1;
                else
                    return value+1;
            }
            else {
                int value=bound.intValue();
                if (value==Integer.MIN_VALUE)
                    return ((long)value)-11;
                else
                    return value-1;
            }
        case 1:
            if (boundIsInclusive)
                return bound;
            else if (BoundaryDirection.LOWER.equals(boundaryDirection)) {
                long value=bound.longValue();
                if (value==Long.MAX_VALUE)
                    return BigInteger.valueOf(value).add(BigInteger.ONE);
                else
                    return value+1;
            }
            else {
                long value=bound.longValue();
                if (value==Long.MIN_VALUE)
                    return BigInteger.valueOf(value).subtract(BigInteger.ONE);
                else
                    return value-1;
            }
        case 2:
            if (boundIsInclusive)
                return bound;
            else if (BoundaryDirection.LOWER.equals(boundaryDirection))
                return ((BigInteger)bound).add(BigInteger.ONE);
            else
                return ((BigInteger)bound).subtract(BigInteger.ONE);
        case 3: {
                // This method assumes that all BigDecimals actually have some decimal digits.
                BigDecimal bd=(BigDecimal)bound;
                assert bd.scale()>0;
                BigInteger bi=bd.toBigInteger();
                if (BoundaryDirection.LOWER.equals(boundaryDirection)) {
                    if (bd.compareTo(BigDecimal.ZERO)>0)
                        bi=bi.add(BigInteger.ONE);
                }
                else {
                    if (bd.compareTo(BigDecimal.ZERO)<0)
                        bi=bi.subtract(BigInteger.ONE);
                }
                int biBitCount=bi.bitCount();
                if (biBitCount<=32)
                    return bi.intValue();
                else if (biBitCount<=64)
                    return bi.longValue();
                else
                    return bi;
            }
        case 4: {
                // This method assumes that all BigRationals are not integers.
                BigRational br=(BigRational)bound;
                BigDecimal numerator=new BigDecimal(br.getNumerator());
                BigDecimal denominator=new BigDecimal(br.getDenominator());
                BigInteger quotient=numerator.divideToIntegralValue(denominator).toBigInteger();
                if (BoundaryDirection.LOWER.equals(boundaryDirection)) {
                    if (numerator.compareTo(BigDecimal.ZERO)>0)
                        quotient=quotient.add(BigInteger.ONE);
                }
                else {
                    if (numerator.compareTo(BigDecimal.ZERO)<0)
                        quotient=quotient.subtract(BigInteger.ONE);
                }
                int quotientBitCount=quotient.bitCount();
                if (quotientBitCount<=32)
                    return quotient.intValue();
                else if (quotientBitCount<=64)
                    return quotient.longValue();
                else
                    return quotient;
            }
        default:
            throw new IllegalArgumentException();
        }
    }
    public static int subtractIntegerIntervalSizeFrom(Number lowerBoundInclusive,Number upperBoundInclusive,int argument) {
        if (argument<=0)
            return 0;
        if (lowerBoundInclusive.equals(upperBoundInclusive))
            return argument;
        int typeLowerBound=getNumberType(lowerBoundInclusive);
        int typeUpperBound=getNumberType(upperBoundInclusive);
        int maxType=Math.max(typeLowerBound,typeUpperBound);
        switch (maxType) {
        case 0: {
                int size=upperBoundInclusive.intValue()-lowerBoundInclusive.intValue()+1;
                if (size<=0)
                    return 0;
                else
                    return Math.max(argument-size,0);
            }
        case 1: {
                long size=upperBoundInclusive.longValue()-lowerBoundInclusive.longValue()+1;
                if (size<=0L)
                    return 0;
                else
                    return (int)Math.max(((long)argument)-size,0);
            }
        case 2: {
                BigInteger leftover=BigInteger.valueOf(argument).subtract(toBigInteger(upperBoundInclusive,typeUpperBound)).add(toBigInteger(lowerBoundInclusive,typeLowerBound)).subtract(BigInteger.ONE);
                if (leftover.compareTo(BigInteger.ZERO)<=0)
                    return 0;
                else
                    return leftover.intValue();
            }
        default:
            throw new IllegalArgumentException();
        }
    }
    public static Number nextInteger(Number integer) {
        switch (getNumberType(integer)) {
        case 0: {
                int value=integer.intValue();
                if (value==Integer.MAX_VALUE)
                    return ((long)value)+1;
                else
                    return value+1;
            }
        case 1: {
                long value=integer.longValue();
                if (value==Long.MAX_VALUE)
                    return BigInteger.valueOf(value).add(BigInteger.ONE);
                else
                    return value+1;
            }
        case 2:
            return ((BigInteger)integer).add(BigInteger.ONE);
        default:
            throw new IllegalArgumentException();
        }
    }
}
TOP

Related Classes of org.semanticweb.HermiT.datatypes.owlreal.Numbers

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.