How to handle numbers in a general way?

My question is very similar to "Writing a generic class for handling built-in types" , including inspired by the fact of working on a class to handle operations on matrices. Although this question was asked using C # and pointed to the article General operators .

I do not understand. The Java number does not have an add method, so you may have a method like this:

public Number myAdd(Number a, Number b){
     return a.add(b);
}

So, how do you handle the case when you want to process several types of numbers in Java?

+5
source share
6 answers

The main problem is that a system like Java is very primitive.

Java ( , Java , Haskell), Number + Number → Number .

( , Integer, ) , + . ( : Number a + Number b, a b ?)

, ( ) , , () .. generics (, ), .

, , , .

+4

. Java ...

, java.lang.Number add, ? ? " "?

, , , API, , , . , " ". / , . ( Java , !)

, , Sun , API-.

+3

? " , ", :

public Number myAdd(Number a, Number b){
     return a.doubleValue() + b.doubleValue();
}

-, , , Java-, , , . , "" Number , BigDecimal, BigInteger, AtomicDouble, AtomicLong, org.apache.commons.lang.mutable, , - .

, - , BigDecimal , Apache Commons 'Fraction.ONE_THIRD; , , , . add() Number Number - , , .

+3

- .

package mixins;

import java.math.BigDecimal;

public class Numbers {

    public static boolean isZ(Number n) {
        return n instanceof Integer || n instanceof Long || n instanceof Short || n instanceof Byte;
    }

    public static boolean isR(Number n) {
        return n instanceof Double || n instanceof Float;
    }

    public static BigDecimal add(BigDecimal a, Number b) {
        if (b instanceof BigDecimal) {
            return a.add((BigDecimal) b);
        } else if (isZ(b)) {
            return a.add(new BigDecimal(b.longValue()));
        } else if (isR(b)) {
            return a.add(new BigDecimal(b.doubleValue()));
        }
        throw new IllegalArgumentException("No valid big decimal translation for " + b.getClass());
    }

    public static Integer add(Integer a, Number b) {
        return a + b.intValue();
    }

    public static Long add(Long a, Number b) {
        return a + b.longValue();
    }

    public static Float add(Float a, Number b) {
        return a + b.floatValue();
    }

    public static Double add(Double a, Number b) {
        return a + b.doubleValue();
    }
}

, .

import static mixins.Numbers.*;

public class Example {

    public static void main(String[] args) {
        BigDecimal fortytwo = new BigDecimal(42);
        BigDecimal fiftyfive = add(fortytwo, 13);
        System.out.println(fiftyfive);
    }

}
+1

, , . Java, - :

interface Arithmetics<T> {
    T add(T val1, T val2);
}

class IntegerArithmetics implements Arithmetics<Integer> {
    Integer add(Integer val1, Integer val2) { return val1 + val2; }
}

//similarly DoubleArithmetics, BigIntegerArithmetics, ...

Java Math .

0

BigDecimals ( , ). . - , , Number. BigDecimal, ?

public BigDecimal myAdd(BigDecimal a, BigDecimal b) {
    return a.add(b);
}

EDIT: To answer the BigBrothers comment below, you can always use the doubleValue () method to create your own generic method. The only problem is that you may lose accuracy in some rare cases when someone IS goes into BigDecimal and more than Double.maxValue

public Number myAdd(Number a, Number b) {
    return new BigDecimal(a.doubleValue() + b.doubleValue());
}

A BigDecimal is a number, so returning one of them makes no difference.

-1
source

All Articles