Skip to content

Commit

Permalink
fix clz23 rounding errors
Browse files Browse the repository at this point in the history
  • Loading branch information
rbri authored and gbrail committed Jan 24, 2024
1 parent e1f9159 commit 553681a
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/org/mozilla/javascript/NativeMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,33 @@ private static Object clz32(Context cx, Scriptable scope, Scriptable thisObj, Ob
if (n == 0) {
return Double32;
}
return Double.valueOf(31 - Math.floor(Math.log(n >>> 0) * LOG2E));

int place = 0;
if ((n & 0xFFFF0000) != 0) {
place += 16;
n >>>= 16;
}
if ((n & 0xFF00) != 0) {
place += 8;
n >>>= 8;
}
if ((n & 0xF0) != 0) {
place += 4;
n >>>= 4;
}
if ((n & 0b1100) != 0) {
place += 2;
n >>>= 2;
}
if ((n & 0b10) != 0) {
place += 1;
n >>>= 1;
}
if ((n & 0b1) != 0) {
place += 1;
}

return Double.valueOf(32 - place);
}

private static Object cos(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
Expand Down
54 changes: 54 additions & 0 deletions testsrc/jstests/harmony/math-clz32.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
load("testsrc/assert.js");

assertEquals(Math.clz32(64), 25);
assertEquals(Math.clz32(0), 32);

assertEquals(Math.clz32(0x00000001), 31);
assertEquals(Math.clz32(0x00000002), 30);
assertEquals(Math.clz32(0x00000004), 29);
assertEquals(Math.clz32(0x00000008), 28);
assertEquals(Math.clz32(0x000000010), 27);
assertEquals(Math.clz32(0x00000020), 26);
assertEquals(Math.clz32(0x00000040), 25);
assertEquals(Math.clz32(0x00000080), 24);
assertEquals(Math.clz32(0x00000100), 23);
assertEquals(Math.clz32(0x00000200), 22);
assertEquals(Math.clz32(0x00000400), 21);
assertEquals(Math.clz32(0x00000800), 20);
assertEquals(Math.clz32(0x00001000), 19);
assertEquals(Math.clz32(0x00002000), 18);
assertEquals(Math.clz32(0x00004000), 17);
assertEquals(Math.clz32(0x00008000), 16);
assertEquals(Math.clz32(0x00010000), 15);
assertEquals(Math.clz32(0x00020000), 14);
assertEquals(Math.clz32(0x00040000), 13);
assertEquals(Math.clz32(0x00080000), 12);
assertEquals(Math.clz32(0x00100000), 11);
assertEquals(Math.clz32(0x00200000), 10);
assertEquals(Math.clz32(0x00400000), 9);
assertEquals(Math.clz32(0x00800000), 8);
assertEquals(Math.clz32(0x01000000), 7);
assertEquals(Math.clz32(0x02000000), 6);
assertEquals(Math.clz32(0x04000000), 5);
assertEquals(Math.clz32(0x08000000), 4);
assertEquals(Math.clz32(0x10000000), 3);
assertEquals(Math.clz32(0x20000000), 2);
assertEquals(Math.clz32(0x40000000), 1);
assertEquals(Math.clz32(0x80000000), 0);
assertEquals(Math.clz32(0xFFFFFFFF), 0);
assertEquals(Math.clz32(0xFFFF0000), 0);
assertEquals(Math.clz32(0x0000FF00), 16);
assertEquals(Math.clz32(0x000000F0), 24);

assertEquals(Math.clz32(-0), 32);
assertEquals(Math.clz32(-1), 0);
assertEquals(Math.clz32(-100), 0);

assertEquals(Math.clz32(1.9), 31);
assertEquals(Math.clz32(Number.POSITIVE_INFINITY), 32);
assertEquals(Math.clz32(Number.NEGATIVE_INFINITY), 32);
assertEquals(Math.clz32(Number.NaN), 32);

assertEquals(Math.clz32(0x1_0000_0100), 23);

"success";
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.mozilla.javascript.tests.harmony;

import org.mozilla.javascript.drivers.RhinoTest;
import org.mozilla.javascript.drivers.ScriptTestsBase;

@RhinoTest(value = "testsrc/jstests/harmony/math-clz32.js")
public class MathClz32Test extends ScriptTestsBase {}

0 comments on commit 553681a

Please sign in to comment.