Bytecoder
Bytecoder copied to clipboard
[BUG] Long.toString(long val, int radix) not working correctly (among other problems)
A bug causes the following statement to give the wrong result:
"20".equals(Long.toString(32L, 16))
This evaluates to true when running in java, but evaluates to false when compiling to wasm and running it in my browser, because Long.toString(32L, 16) wrongly evaluates to 32.
Platform
OS: Windows 10 (version 2004, build 19041.685) Browser: tested both Firefox (version 84.0.1) and Edge Chromium (version 87.0.664.75) Java: OpenJDK 14.0.2 Bytecoder dep/plugin: 2020-12-01
I've also been verifying other things. Here is what I have tested so far (see link for the code):
booleans:
"true".equals(Boolean.toString(true)): true
"true".equals("" + true): true
"false".equals(Boolean.toString(false)): true
"false".equals("" + false): true
"true".equals("" + (true || false)): true
"false".equals("" + (true && false)): true
"true".equals("" + (true | false)): true
"false".equals("" + (true & false)): true
"false".equals("" + !true): true
integers:
"0".equals(Integer.toString(0)): true
"0".equals("" + 0): true
"1".equals("" + 1): true
"2".equals(Integer.toString(1+1)): true
"2".equals("" + (1+1)): true
"4".equals("" + (2*2)): true
"20".equals(Integer.toString(32, 16)): true
longs:
"0".equals(Long.toString(0L)): true
"0".equals("" + 0L): true
"1".equals("" + 1L): true
"2".equals(Long.toString(1L+1L)): true
"2".equals("" + (1L+1L)): true
"4".equals("" + (2L*2L)): true
"20".equals(Long.toString(32, 16)): false
----------------------------------------------
Assertion error!
"20" expected, but got "32"
----------------------------------------------
BigIntegers:
"0".equals("" + BigInteger.ZERO.longValue()): true
"1".equals("" + BigInteger.ONE.longValue()): true
"2".equals("" + BigInteger.TWO.longValue()): true
"10".equals("" + BigInteger.TEN.longValue()): true
"15".equals("" + BigInteger.valueOf(15).longValue()): true
"100".equals("" + BigInteger.valueOf(100).longValue()): false
----------------------------------------------
Assertion error!
"100" expected, but got "200"
----------------------------------------------
"1000000000000000000".equals("" + BigInteger.valueOf(1000000000000000000L).longValue()): false
----------------------------------------------
Assertion error!
"1000000000000000000" expected, but got "1321730187"
----------------------------------------------
"1000000000000000000".equals("" + BigInteger.valueOf(0xde0b6b3a7640000L).longValue()): false
----------------------------------------------
Assertion error!
"1000000000000000000" expected, but got "1321730187"
----------------------------------------------
"0".equals("" + BigInteger.ZERO): true
"1".equals("" + BigInteger.ONE): false
----------------------------------------------
Assertion error!
"1" expected, but got "-2"
----------------------------------------------
"2".equals("" + BigInteger.TWO): false
----------------------------------------------
Assertion error!
"2" expected, but got "-3"
----------------------------------------------
"10".equals("" + BigInteger.TEN): false
----------------------------------------------
Assertion error!
"10" expected, but got "-11"
----------------------------------------------
"15".equals("" + BigInteger.valueOf(15)): false
----------------------------------------------
Assertion error!
"15" expected, but got "-16"
----------------------------------------------
"100".equals("" + BigInteger.valueOf(100)): false
----------------------------------------------
Assertion error!
"100" expected, but got "-201"
----------------------------------------------
"1000000000000000000".equals("" + BigInteger.valueOf(1000000000000000000L)): false
----------------------------------------------
Assertion error!
"1000000000000000000" expected, but got "-1000000000000000000"
----------------------------------------------
"1000000000000000000".equals("" + BigInteger.valueOf(0xde0b6b3a7640000L)): false
----------------------------------------------
Assertion error!
"1000000000000000000" expected, but got "-1000000000000000000"
----------------------------------------------
Note that these tests all succeed in Java
I also tried running "de0b6b3a7640000".equals("" + BigInteger.valueOf(0xde0b6b3a7640000L).toString(16)), which works without issues in Java, but throws an 'uncaught (in promise) error' to the commandline in my browser
Platform
OS: Windows 10 (version 2004, build 19041.685) Browser: tested both Firefox (version 84.0.1) and Edge Chromium (version 87.0.664.75) Java: OpenJDK 14.0.2 Bytecoder dep/plugin: 2020-12-01
I verified that this bug also happens when setting release to java 9 and java 11 with the openjdk 14.0.2 compiler and when setting release to java 11 with the jetbrains 11.0.9.1 compiler
Also, when targeting the js backend and setting release to java 11 (anything higher gives a compiler error), I get the following result:
booleans:
"true".equals(Boolean.toString(true)): true
"true".equals("" + true): true
"false".equals(Boolean.toString(false)): true
"false".equals("" + false): true
"true".equals("" + (true || false)): true
"false".equals("" + (true && false)): true
"true".equals("" + (true | false)): true
"false".equals("" + (true & false)): true
"false".equals("" + !true): true
integers:
"0".equals(Integer.toString(0)): true
"0".equals("" + 0): true
"1".equals("" + 1): true
"2".equals(Integer.toString(1+1)): true
"2".equals("" + (1+1)): true
"4".equals("" + (2*2)): true
"20".equals(Integer.toString(32, 16)): true
longs:
"0".equals(Long.toString(0L)): true
"0".equals("" + 0L): true
"1".equals("" + 1L): true
"2".equals(Long.toString(1L+1L)): true
"2".equals("" + (1L+1L)): true
"4".equals("" + (2L*2L)): true
"20".equals(Long.toString(32, 16)): false
----------------------------------------------
Assertion error!
"20" expected, but got "32"
----------------------------------------------
2
BigIntegers:
"0".equals("" + BigInteger.ZERO.longValue()): true
"1".equals("" + BigInteger.ONE.longValue()): true
"2".equals("" + BigInteger.TWO.longValue()): true
"10".equals("" + BigInteger.TEN.longValue()): true
"15".equals("" + BigInteger.valueOf(15).longValue()): true
"100".equals("" + BigInteger.valueOf(100).longValue()): false
----------------------------------------------
Assertion error!
"100" expected, but got "200"
----------------------------------------------
"1000000000000000000".equals("" + BigInteger.valueOf(1000000000000000000L).longValue()): false
----------------------------------------------
Assertion error!
"1000000000000000000" expected, but got "-2973237248"
----------------------------------------------
"1000000000000000000".equals("" + BigInteger.valueOf(0xde0b6b3a7640000L).longValue()): false
----------------------------------------------
Assertion error!
"1000000000000000000" expected, but got "-2973237248"
----------------------------------------------
"0".equals("" + BigInteger.ZERO): true
"1".equals("" + BigInteger.ONE): true
"2".equals("" + BigInteger.TWO): true
"10".equals("" + BigInteger.TEN): true
"15".equals("" + BigInteger.valueOf(15)): true
"100".equals("" + BigInteger.valueOf(100)): false
----------------------------------------------
Assertion error!
"100" expected, but got "200"
----------------------------------------------
"1000000000000000000".equals("" + BigInteger.valueOf(1000000000000000000L)): true
"1000000000000000000".equals("" + BigInteger.valueOf(0xde0b6b3a7640000L)): true
As you can see, BigInteger seems to work better with a js backend, but it still has issues with numbers higher than 16 (numbers between -16 and 16 are the numbers that are precomputed statically).
Also related to #265. The only Bytecoder backend supporting BigInteger is the wasm_llvm backend.
Closed due to no further feedback.
Closed due to no further feedback.
What further feedback was there to give? I gave you a detailed description of testcases that don't evaluate correctly and supplied the platform for which this was an issue.
Were you able to reproduce the bug? You never asked for clarification or extra examples or details to be able to reproduce it.