From 06c74072be9e9e5d389b123166a1f11818badf5b Mon Sep 17 00:00:00 2001 From: UnlegitDqrk Date: Mon, 2 Mar 2026 15:31:22 +0100 Subject: [PATCH] Fixed issue: #47 --- .../luaj/vm2/libs/ApproxLib$approx_eq.class | Bin 0 -> 961 bytes .../java/org/luaj/vm2/libs/ApproxLib.class | Bin 0 -> 1215 bytes .../java/org/luaj/vm2/libs/ApproxLib.java | 51 ++++++++++++++++++ .../org/luaj/vm2/libs/jse/LuaStateSync.class | Bin 0 -> 1252 bytes .../org/luaj/vm2/libs/jse/LuaStateSync.java | 41 ++++++++++++++ .../test/java/org/luaj/vm2/FragmentsTest.java | 17 ++++++ .../java/org/luaj/vm2/LuaOperationsTest.java | 11 ++++ 7 files changed, 120 insertions(+) create mode 100644 core/src/main/java/org/luaj/vm2/libs/ApproxLib$approx_eq.class create mode 100644 core/src/main/java/org/luaj/vm2/libs/ApproxLib.class create mode 100644 core/src/main/java/org/luaj/vm2/libs/ApproxLib.java create mode 100644 jse/src/main/java/org/luaj/vm2/libs/jse/LuaStateSync.class create mode 100644 jse/src/main/java/org/luaj/vm2/libs/jse/LuaStateSync.java diff --git a/core/src/main/java/org/luaj/vm2/libs/ApproxLib$approx_eq.class b/core/src/main/java/org/luaj/vm2/libs/ApproxLib$approx_eq.class new file mode 100644 index 0000000000000000000000000000000000000000..db40e97163930fbe1af7872573eb7aeaca38803c GIT binary patch literal 961 zcma)4+fEZv6kVs6nKBGl3kv(m1E>!KB|!?YNkJ0~CcK!__E?5a=ae%ujXz@I zgCC(UNPO@E`~bhfuORNJK+>Rz4`=Ul+iUN=*8Xwv?K^-SJkgP0n3byOco9Ewy6rW` zb8CUK)#)htzUtNtq>$F3nb478$lv^W$kmo=?nZt+bfwRrJ#~FI++;}Fg+l`d26dPw zhA_;K?F*+!u9^YEVEtIsTMZf2Ji(B%D}}PQIaV6{we<5tj4*EE7P1TjvJ+nYO52rk zp`5`ap^8r6deYCgqae)JM1J#Ge#L-=X&o~rW--UG*q6D##|7T&_N_Q&$WTQ>DXAD9 z*p=!D?{dfEe$zP!mFqV*3e`TKYQzt@7l{o63^^0Gk*9Y4;O(47+#^2ha=BbMGH@67 zbS#)y#1g~AUtt*ZZVdPG9mAY`bTip=DLuh`N@u|~QNS`KaQ&`q5pj;)U)&|X|E!s) z-j)pt9I3j#*pJ#Zpk=1&alVph~vhmjz-Db$I7E@;!s1(y=*Hc9;i;**ot!tJx{P7bEZG7S! zQ*Uf5WohS_KgXTV6qM+}&JYBs5)IQd)-#x*5zAqYgw5e0y--ybSWG69qg#}?L{V|# r9Qg!!ZMk@c`!QO7kq+IYsfp3JxfMDju!^;wXLv+D9x;p7V_3fdn|jza literal 0 HcmV?d00001 diff --git a/core/src/main/java/org/luaj/vm2/libs/ApproxLib.class b/core/src/main/java/org/luaj/vm2/libs/ApproxLib.class new file mode 100644 index 0000000000000000000000000000000000000000..fe64491a076bf3c2fd4d4787e2108f43c95864ef GIT binary patch literal 1215 zcmZ`(-A)rh6#jcA>jP9z+u* z@!A_M^gxOioKsRi-Wvotr@#2{E$SYpoVL>PN0tA zGQ=afO}@udWp0&HOK!!qN|U*Ug2ZB(m#fC4fbAsK^^z(=2r9U73F%t84?PUc|G_Kh z({K~F2)QJXM=n8*UIDG*Htr}G&@hN0hV~1}x?LrO$hA>33Uj+{GA!{{m@|yKjg)FP@jyMe2PG z4=_&dZN4uqN7tjef=3KJ4H`CH3PYQonNPpW71lB@ma@6$#EIz)t#h{JxZHAU0(z$d z$(G;YU+;mimQdcB`D~dg(lR zbd{JbxqN+Vk?)-2s!MjYvTn?qLVADtU$-TNT2v%&IPRh$c#>9H*0PMsT$wwL;gIML z>74)!-I%~*nkQ-1gegd5)61c8nmm0pGnzfIW3aEa4NqtkVL+vE25A~aY5_9+fcPnt z70Gjq=6oWkox;CzjP@f0;=zu@5xU~RZgL-?m+ZtB%4ZN2I|&qMqnhpLLV!9nh#0+) zX3S#l9N`<`s+9FAe1iT6{oftHBOlT#d;pak;g9f0VjZimWA$~Ubb`c$H{=b;A3mM$ zNKks>1otL<= 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; + } +} diff --git a/jse/src/main/java/org/luaj/vm2/libs/jse/LuaStateSync.class b/jse/src/main/java/org/luaj/vm2/libs/jse/LuaStateSync.class new file mode 100644 index 0000000000000000000000000000000000000000..7156ad6df9c78199405d610e51bcb624aff0cad5 GIT binary patch literal 1252 zcmb7@ZBNrs6vzK}8!MC!7!NXJ;6NU_4cCE>Fd#vO$&x8AW=Qm1H!icYYiHLI^pi;9 zN8pWbV9`Y1`bAJDG&i(Q0%QpZA*pU%JSVBa>0HO?I4gFNt zOx>z$ht&qJxeU>5!!q1mhOnAGk}$}yczvj3n!K)?drsYJa?3q9tMQg=*w!FqhDqLP z8>VfgnqJ#YRe5T6CzY2WK@r(v3{z_PI#k7V469y9AITWSn1r~3aZJ!5+o@}&r#H0I z=7v`G^dsH$IN{Ve(dE_hjrKyi&vy}hO2I8mGYlGS%WGD-V=*!6y5`)KXfGApvKF|6HG?SN;m4Ki}jB;*yW zV}n{A6x?WY(T$3$yS(z=sxgccWa*?^i2XM-L;RTG{(mz6snr8P{g5H4mVy;3SuU@0 zr@#=|w~whuqh-V5-MYQh{jS9btoHV~-s! zs4;rR=|6!4CW&$ic}!!Ic2DT!5JK^vV%SH0j?Es&5^+QYVJ6!_#?Nz41n$xcaX`}d z*a~>ec4!O)S->Mj9(1F69#4BYW&&DQy27rNj37)2mq^JnDOvT&!(efWR3JkL+rI&l Cl@= 0"); + } + LuaValue current = target.get(key); + if (current.isnumber() && ApproxLib.approxEqual(current.todouble(), value, epsilon)) { + return false; + } + target.set(key, LuaValue.valueOf(value)); + return true; + } + + public static boolean setIfApproxChanged(LuaValue target, String key, double value, double epsilon) { + return setIfApproxChanged(target, LuaValue.valueOf(key), value, epsilon); + } + + public static boolean setIfApproxChanged(LuaValue target, int key, double value, double epsilon) { + return setIfApproxChanged(target, LuaValue.valueOf(key), value, epsilon); + } + + public static boolean approxEqual(double a, double b, double epsilon) { + if (epsilon < 0d) { + throw new IllegalArgumentException("epsilon must be >= 0"); + } + return ApproxLib.approxEqual(a, b, epsilon); + } +} diff --git a/jse/src/test/java/org/luaj/vm2/FragmentsTest.java b/jse/src/test/java/org/luaj/vm2/FragmentsTest.java index 58c6c656..db3455cf 100644 --- a/jse/src/test/java/org/luaj/vm2/FragmentsTest.java +++ b/jse/src/test/java/org/luaj/vm2/FragmentsTest.java @@ -32,6 +32,7 @@ import junit.framework.TestCase; import junit.framework.TestSuite; import org.luaj.vm2.libs.jse.JsePlatform; +import org.luaj.vm2.libs.ApproxLib; import org.luaj.vm2.luajc.LuaJC; /** @@ -373,6 +374,22 @@ public class FragmentsTest extends TestSuite { "end\n"); } + public void testApproxEqLibrary() { + try { + Globals globals = JsePlatform.standardGlobals(); + globals.load(new ApproxLib()); + Varargs result = globals.load( + "return approx_eq(1.0, 0.9999999995, 1e-8), " + + "approx.eq(1.0, 0.9, 1e-8)\n", + "approx.lua").invoke(); + assertEquals(LuaValue.TRUE, result.arg1()); + assertEquals(LuaValue.FALSE, result.arg(2)); + } catch (Exception e) { + e.printStackTrace(); + fail(e.toString()); + } + } + public void testTableMove() { runFragment( LuaValue.varargsOf(new LuaValue[] { diff --git a/jse/src/test/java/org/luaj/vm2/LuaOperationsTest.java b/jse/src/test/java/org/luaj/vm2/LuaOperationsTest.java index 84119a57..036ed655 100644 --- a/jse/src/test/java/org/luaj/vm2/LuaOperationsTest.java +++ b/jse/src/test/java/org/luaj/vm2/LuaOperationsTest.java @@ -30,6 +30,7 @@ import junit.framework.TestCase; import org.luaj.vm2.TypeTest.MyData; import org.luaj.vm2.libs.ZeroArgFunction; import org.luaj.vm2.libs.jse.JsePlatform; +import org.luaj.vm2.libs.jse.LuaStateSync; public class LuaOperationsTest extends TestCase { @@ -173,4 +174,14 @@ public class LuaOperationsTest extends TestCase { assertEquals( eee, c.call() ); } } + + public void testSetIfApproxChanged() { + LuaTable target = LuaValue.tableOf(); + assertTrue(LuaStateSync.setIfApproxChanged(target, "height", 1.0d, 1e-6d)); + assertEquals(LuaValue.valueOf(1.0d), target.get("height")); + assertFalse(LuaStateSync.setIfApproxChanged(target, "height", 0.999999999d, 1e-6d)); + assertEquals(LuaValue.valueOf(1.0d), target.get("height")); + assertTrue(LuaStateSync.setIfApproxChanged(target, "height", 1.1d, 1e-6d)); + assertEquals(LuaValue.valueOf(1.1d), target.get("height")); + } }