Fixed issue: #47
This commit is contained in:
BIN
core/src/main/java/org/luaj/vm2/libs/ApproxLib$approx_eq.class
Normal file
BIN
core/src/main/java/org/luaj/vm2/libs/ApproxLib$approx_eq.class
Normal file
Binary file not shown.
BIN
core/src/main/java/org/luaj/vm2/libs/ApproxLib.class
Normal file
BIN
core/src/main/java/org/luaj/vm2/libs/ApproxLib.class
Normal file
Binary file not shown.
51
core/src/main/java/org/luaj/vm2/libs/ApproxLib.java
Normal file
51
core/src/main/java/org/luaj/vm2/libs/ApproxLib.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package org.luaj.vm2.libs;
|
||||
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
/**
|
||||
* Optional helpers for approximate floating-point comparisons.
|
||||
* This deliberately does not change Lua's core equality semantics.
|
||||
*/
|
||||
public class ApproxLib extends TwoArgFunction {
|
||||
|
||||
private static final double DEFAULT_EPSILON = 1e-9d;
|
||||
|
||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
||||
LuaTable lib = new LuaTable(0, 2);
|
||||
lib.set("eq", new approx_eq());
|
||||
env.set("approx", lib);
|
||||
env.set("approx_eq", lib.get("eq"));
|
||||
return lib;
|
||||
}
|
||||
|
||||
static final class approx_eq extends VarArgFunction {
|
||||
public LuaValue invoke(org.luaj.vm2.Varargs args) {
|
||||
double a = args.checkdouble(1);
|
||||
double b = args.checkdouble(2);
|
||||
double epsilon = args.optdouble(3, DEFAULT_EPSILON);
|
||||
if (epsilon < 0d) {
|
||||
argerror(3, "epsilon must be >= 0");
|
||||
}
|
||||
return LuaValue.valueOf(approxEqual(a, b, epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean approxEqual(double a, double b, double epsilon) {
|
||||
if (Double.doubleToLongBits(a) == Double.doubleToLongBits(b)) {
|
||||
return true;
|
||||
}
|
||||
if (Double.isNaN(a) || Double.isNaN(b)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.isInfinite(a) || Double.isInfinite(b)) {
|
||||
return false;
|
||||
}
|
||||
double diff = Math.abs(a - b);
|
||||
if (diff <= epsilon) {
|
||||
return true;
|
||||
}
|
||||
double scale = Math.max(Math.abs(a), Math.abs(b));
|
||||
return diff <= scale * epsilon;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user