All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sandius.rembulan.Arithmetic Maven / Gradle / Ivy

There is a newer version: 1.0.3
Show newest version
/*
 * Copyright 2016 Miroslav Janíček
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.sandius.rembulan;

/**
 * A representation of one of the two arithmetic modes (integer or float).
 *
 * 

This class serves as a bridge between the representation of Lua numbers as * {@link java.lang.Number} and the appropriate dispatch of arithmetic operations * via the methods of {@link net.sandius.rembulan.LuaMathOperators}.

* *

There are two concrete instances of this class, {@link #FLOAT} (the float * arithmetic) and {@link #INTEGER} (the integer arithmetic). In order to obtain * the correct instance for the given numbers, use the static methods * {@link #of(Number, Number)} (for lookup based on two arguments, i.e. for binary * operations) or {@link #of(Number)} (for lookup based on a single argument, i.e. * for unary minus).

* *

The arithmetic methods of this class yield boxed results.

* *

Example: Given two objects {@code a} and {@code b} of type {@code Number}, * use the {@code Arithmetic} class to compute the value of the Lua expression * {@code (a // b)}:

* *
 *   // Number a, b
 *   final Number result;
 *   Arithmetic m = Arithmetic.of(a, b);
 *   if (m != null) {
 *       result = m.idiv(a, b);
 *   }
 *   else {
 *       throw new IllegalStateException("a or b is nil");
 *   }
 * 
*/ public abstract class Arithmetic { private Arithmetic() { // not to be instantiated by the outside world } /** * Integer arithmetic. * *

Invokes arithmetic operations from {@link LuaMathOperators} with all arguments * converted to Lua integers (i.e. {@code long}s).

*/ public static final Arithmetic INTEGER = new IntegerArithmetic(); /** * Float arithmetic. * *

Invokes arithmetic operations from {@link LuaMathOperators} with all arguments * converted to Lua floats (i.e. {@code double}s).

*/ public static final Arithmetic FLOAT = new FloatArithmetic(); /** * Returns the boxed result of the Lua addition of the two numbers * {@code a} and {@code b}. * * @param a first addend, must not be {@code null} * @param b second addend, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (a + b)} * * @throws NullPointerException if {@code a} or {@code b} is {@code null} */ public abstract Number add(Number a, Number b); /** * Returns the boxed result of the Lua subtraction of the two numbers * {@code a} and {@code b}. * * @param a the minuend, must not be {@code null} * @param b the subtrahend, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (a - b)} * * @throws NullPointerException if {@code a} or {@code b} is {@code null} */ public abstract Number sub(Number a, Number b); /** * Returns the boxed result of the Lua multiplication of the two numbers * {@code a} and {@code b}. * * @param a first factor, must not be {@code null} * @param b second factor, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (a * b)} * * @throws NullPointerException if {@code a} or {@code b} is {@code null} */ public abstract Number mul(Number a, Number b); /** * Returns the boxed result of the Lua float division of the two numbers * {@code a} and {@code b}. * * @param a the dividend, must not be {@code null} * @param b the divisor, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (a / b)} * * @throws NullPointerException if {@code a} or {@code b} is {@code null} */ public abstract Double div(Number a, Number b); /** * Returns the boxed result of the Lua modulo of the two numbers * {@code a} and {@code b}. * * @param a the dividend, must not be {@code null} * @param b the divisor, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (a % b)} * * @throws NullPointerException if {@code a} or {@code b} is {@code null} */ public abstract Number mod(Number a, Number b); /** * Returns the boxed result of the Lua floor division of the two numbers * {@code a} and {@code b}. * * @param a the dividend, must not be {@code null} * @param b the divisor, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (a // b)} * * @throws NullPointerException if {@code a} or {@code b} is {@code null} */ public abstract Number idiv(Number a, Number b); /** * Returns the boxed result of the Lua exponentiation of the two numbers * {@code a} and {@code b}. * * @param a the base, must not be {@code null} * @param b the exponent, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (a ^ b)} * * @throws NullPointerException if {@code a} or {@code b} is {@code null} */ public abstract Double pow(Number a, Number b); /** * Returns the boxed result of the Lua arithmetic negation of the number * {@code n}. * * @param n the operand, must not be {@code null} * @return the (boxed) value of the Lua expression {@code (-n)} * * @throws NullPointerException if {@code n} is {@code null} */ public abstract Number unm(Number n); private static final class IntegerArithmetic extends Arithmetic { @Override public Long add(Number a, Number b) { return LuaMathOperators.add(a.longValue(), b.longValue()); } @Override public Long sub(Number a, Number b) { return LuaMathOperators.sub(a.longValue(), b.longValue()); } @Override public Long mul(Number a, Number b) { return LuaMathOperators.mul(a.longValue(), b.longValue()); } @Override public Double div(Number a, Number b) { return LuaMathOperators.div(a.longValue(), b.longValue()); } @Override public Long mod(Number a, Number b) { return LuaMathOperators.mod(a.longValue(), b.longValue()); } @Override public Long idiv(Number a, Number b) { return LuaMathOperators.idiv(a.longValue(), b.longValue()); } @Override public Double pow(Number a, Number b) { return LuaMathOperators.pow(a.longValue(), b.longValue()); } @Override public Long unm(Number n) { return LuaMathOperators.unm(n.longValue()); } } private static final class FloatArithmetic extends Arithmetic { @Override public Double add(Number a, Number b) { return LuaMathOperators.add(a.doubleValue(), b.doubleValue()); } @Override public Double sub(Number a, Number b) { return LuaMathOperators.sub(a.doubleValue(), b.doubleValue()); } @Override public Double mul(Number a, Number b) { return LuaMathOperators.mul(a.doubleValue(), b.doubleValue()); } @Override public Double div(Number a, Number b) { return LuaMathOperators.div(a.doubleValue(), b.doubleValue()); } @Override public Double mod(Number a, Number b) { return LuaMathOperators.mod(a.doubleValue(), b.doubleValue()); } @Override public Double idiv(Number a, Number b) { return LuaMathOperators.idiv(a.doubleValue(), b.doubleValue()); } @Override public Double pow(Number a, Number b) { return LuaMathOperators.pow(a.doubleValue(), b.doubleValue()); } @Override public Double unm(Number n) { return LuaMathOperators.unm(n.doubleValue()); } } /** * Return an arithmetic based on the concrete types of the arguments {@code a} * and {@code b}. * *

If either of {@code a} or {@code b} is {@code null}, returns {@code null}. * Otherwise, if either of {@code a} or {@code b} a Lua float, returns {@link #FLOAT}. * If {@code a} and {@code b} are both Lua integers, returns {@link #INTEGER}.

* * @param a first argument, may be {@code null} * @param b second argument, may be {@code null} * @return {@code null} if {@code a} or {@code b} is {@code null}; * {@link #FLOAT} if {@code a} or {@code b} is a Lua float; * {@link #INTEGER} if {@code a} and {@code b} are Lua integers */ public static Arithmetic of(Number a, Number b) { if (a == null || b == null) { return null; } else if ((a instanceof Double || a instanceof Float) || (b instanceof Double || b instanceof Float)) { return FLOAT; } else { return INTEGER; } } /** * Return an arithmetic based on the concrete type of the argument {@code n}. * * If {@code n} is {@code null}, returns {@code null}; otherwise, returns * {@link #FLOAT} if {@code n} is a Lua float, or {@link #INTEGER} if {@code n} * is a Lua integer. * * @param n the argument, may be {@code null} * @return {@code null} if {@code n} is {@code null}; * {@link #FLOAT} if {@code n} is a Lua float; * {@link #INTEGER} if {@code n} is a Lua integer */ public static Arithmetic of(Number n) { if (n == null) { return null; } else if (n instanceof Double || n instanceof Float) { return FLOAT; } else { return INTEGER; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy