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

org.luaj.vm2.lib.MathLib Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
* Copyright (c) 2009 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.lib;

import java.util.Random;

import org.luaj.vm2.LuaDouble;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;

/** 
 * Subclass of {@link LibFunction} which implements the lua standard {@code math} 
 * library. 
 * 

* It contains only the math library support that is possible on JME. * For a more complete implementation based on math functions specific to JSE * use {@link org.luaj.vm2.lib.jse.JseMathLib}. * In Particular the following math functions are not implemented by this library: *

    *
  • acos
  • *
  • asin
  • *
  • atan
  • *
  • cosh
  • *
  • log
  • *
  • sinh
  • *
  • tanh
  • *
  • atan2
  • *
*

* The implementations of {@code exp()} and {@code pow()} are constructed by * hand for JME, so will be slower and less accurate than when executed on the JSE platform. *

* Typically, this library is included as part of a call to either * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or * {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} *

 {@code
 * Globals globals = JsePlatform.standardGlobals();
 * System.out.println( globals.get("math").get("sqrt").call( LuaValue.valueOf(2) ) );
 * } 
* When using {@link org.luaj.vm2.lib.jse.JsePlatform} as in this example, * the subclass {@link org.luaj.vm2.lib.jse.JseMathLib} will * be included, which also includes this base functionality. *

* To instantiate and use it directly, * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: *

 {@code
 * Globals globals = new Globals();
 * globals.load(new JseBaseLib());
 * globals.load(new PackageLib());
 * globals.load(new MathLib());
 * System.out.println( globals.get("math").get("sqrt").call( LuaValue.valueOf(2) ) );
 * } 
* Doing so will ensure the library is properly initialized * and loaded into the globals table. *

* This has been implemented to match as closely as possible the behavior in the corresponding library in C. * @see LibFunction * @see org.luaj.vm2.lib.jse.JsePlatform * @see org.luaj.vm2.lib.jme.JmePlatform * @see org.luaj.vm2.lib.jse.JseMathLib * @see Lua 5.2 Math Lib Reference */ public class MathLib extends TwoArgFunction { /** Pointer to the latest MathLib instance, used only to dispatch * math.exp to tha correct platform math library. */ public static MathLib MATHLIB = null; /** Construct a MathLib, which can be initialized by calling it with a * modname string, and a global environment table as arguments using * {@link #call(LuaValue, LuaValue)}. */ public MathLib() { MATHLIB = this; } /** Perform one-time initialization on the library by creating a table * containing the library functions, adding that table to the supplied environment, * adding the table to package.loaded, and returning table as the return value. * @param modname the module name supplied if this is loaded via 'require'. * @param env the environment to load into, typically a Globals instance. */ public LuaValue call(LuaValue modname, LuaValue env) { LuaTable math = new LuaTable(0,30); math.set("abs", new abs()); math.set("ceil", new ceil()); math.set("cos", new cos()); math.set("deg", new deg()); math.set("exp", new exp(this)); math.set("floor", new floor()); math.set("fmod", new fmod()); math.set("frexp", new frexp()); math.set("huge", LuaDouble.POSINF ); math.set("ldexp", new ldexp()); math.set("max", new max()); math.set("min", new min()); math.set("modf", new modf()); math.set("pi", Math.PI ); math.set("pow", new pow()); random r; math.set("random", r = new random()); math.set("randomseed", new randomseed(r)); math.set("rad", new rad()); math.set("sin", new sin()); math.set("sqrt", new sqrt()); math.set("tan", new tan()); env.set("math", math); env.get("package").get("loaded").set("math", math); return math; } abstract protected static class UnaryOp extends OneArgFunction { public LuaValue call(LuaValue arg) { return valueOf(call(arg.checkdouble())); } abstract protected double call(double d); } abstract protected static class BinaryOp extends TwoArgFunction { public LuaValue call(LuaValue x, LuaValue y) { return valueOf(call(x.checkdouble(), y.checkdouble())); } abstract protected double call(double x, double y); } static final class abs extends UnaryOp { protected double call(double d) { return Math.abs(d); } } static final class ceil extends UnaryOp { protected double call(double d) { return Math.ceil(d); } } static final class cos extends UnaryOp { protected double call(double d) { return Math.cos(d); } } static final class deg extends UnaryOp { protected double call(double d) { return Math.toDegrees(d); } } static final class floor extends UnaryOp { protected double call(double d) { return Math.floor(d); } } static final class rad extends UnaryOp { protected double call(double d) { return Math.toRadians(d); } } static final class sin extends UnaryOp { protected double call(double d) { return Math.sin(d); } } static final class sqrt extends UnaryOp { protected double call(double d) { return Math.sqrt(d); } } static final class tan extends UnaryOp { protected double call(double d) { return Math.tan(d); } } static final class exp extends UnaryOp { final MathLib mathlib; exp(MathLib mathlib) { this.mathlib = mathlib; } protected double call(double d) { return mathlib.dpow_lib(Math.E,d); } } static final class fmod extends BinaryOp { protected double call(double x, double y) { double q = x/y; return x - y * (q>=0? Math.floor(q): Math.ceil(q)); } } static final class ldexp extends BinaryOp { protected double call(double x, double y) { // This is the behavior on os-x, windows differs in rounding behavior. return x * Double.longBitsToDouble((((long) y) + 1023) << 52); } } static final class pow extends BinaryOp { protected double call(double x, double y) { return MathLib.dpow_default(x, y); } } static class frexp extends VarArgFunction { public Varargs invoke(Varargs args) { double x = args.checkdouble(1); if ( x == 0 ) return varargsOf(ZERO,ZERO); long bits = Double.doubleToLongBits( x ); double m = ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52))); double e = (((int) (bits >> 52)) & 0x7ff) - 1022; return varargsOf( valueOf(m), valueOf(e) ); } } static class max extends VarArgFunction { public Varargs invoke(Varargs args) { double m = args.checkdouble(1); for ( int i=2,n=args.narg(); i<=n; ++i ) m = Math.max(m,args.checkdouble(i)); return valueOf(m); } } static class min extends VarArgFunction { public Varargs invoke(Varargs args) { double m = args.checkdouble(1); for ( int i=2,n=args.narg(); i<=n; ++i ) m = Math.min(m,args.checkdouble(i)); return valueOf(m); } } static class modf extends VarArgFunction { public Varargs invoke(Varargs args) { double x = args.checkdouble(1); double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x ); double fracPart = x - intPart; return varargsOf( valueOf(intPart), valueOf(fracPart) ); } } static class random extends LibFunction { Random random = new Random(); public LuaValue call() { return valueOf( random.nextDouble() ); } public LuaValue call(LuaValue a) { int m = a.checkint(); if (m<1) argerror(1, "interval is empty"); return valueOf( 1 + random.nextInt(m) ); } public LuaValue call(LuaValue a, LuaValue b) { int m = a.checkint(); int n = b.checkint(); if (n 0; whole>>=1, v*=v ) if ( (whole & 1) != 0 ) p *= v; if ( (b -= whole) > 0 ) { int frac = (int) (0x10000 * b); for ( ; (frac&0xffff)!=0; frac<<=1 ) { a = Math.sqrt(a); if ( (frac & 0x8000) != 0 ) p *= a; } } return p; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy