zackster
05/08/2023, 9:24 AMAdam Cameron
why might converting decimal -1234 to hex result in 0xfffffb2e rather than -0x4D2
When converting decimal -1234 to a 32-bit two's complement representation in hexadecimal, the correct result is -0x4D2. However, if you try to convert the decimal number to an unsigned 32-bit representation in hexadecimal, you may get 0xfffffb2e as the result.
This happens because when a decimal number is converted to hexadecimal, it is first converted to its binary representation. In the case of -1234, the binary representation in 32-bit two's complement form is 0b11111111111111111111100110101110.
If you interpret this binary number as an unsigned integer, you get 4294966062 (0xfffffb2e in hexadecimal). However, if you interpret it as a 32-bit two's complement signed integer, you get -1234 (which is represented as 0xfffffb2e in hexadecimal).
Therefore, it is important to specify whether you want to convert the decimal number to an unsigned or a signed hexadecimal representation, depending on the context of your problem.
Adam Cameron
zackster
05/08/2023, 9:48 AMAdam Cameron
Adam Cameron
// cf / lucee
writeDump(formatBaseN(-1234,16)); // fffffb2e / -4d2
writeDump(formatBaseN(1234,16)); // 4d2
writeDump(inputBaseN("fffffb2e", 16)); // 4294966062
writeDump(inputBaseN("-4d2", 16)); // -1234
Re round trip... it would seem reasonable to me that formatBaseN
and inputBaseN
follow the same rules re signed/unsigned intszackster
05/08/2023, 10:11 AMAdam Cameron
echo dechex(-1234); // fffffffffffffb2e
echo PHP_EOL;
echo dechex(1234); // 4d2
JS:
(-1234).toString(16)
'-4d2'
(1234).toString(16)
'4d2'
Ruby:
irb(main):001:0> -1234.to_s(16)
=> "-4d2"
Python:
>>> print(hex(-1234))
-0x4d2
Groovy:
groovy> Integer.toHexString(-1234)
Result: fffffb2e
Java (via CFML...):
(https://trycf.com/gist/909a4e1cbc53f26b32b6d5de30c3d72a/lucee5?theme=monokai)
Long = createObject("java", "java.lang.Long")
l = createObject("java", "java.lang.Long").init(-1234)
n = -1234
writeDump([
l = [
type = l.getClass().getName(), // java.lang.Long
hex = Long.toHexString(l) // fffffffffffffb2e
],
n = [
type = n.getClass().getName(), // java.lang.Double
hex = Long.toHexString(n) // fffffffffffffb2e
]
])
Adam Cameron
zackster
05/08/2023, 10:19 AMAdam Cameron
user=> (Integer/toString -1234 16)
"-4d2"
Given it's a JVM language 'n' all. Indicates perhaps that my Java code is not the final word on how it works in Java. There's no doubt some (un)signed idiosyncracy that we ought to be considering.Adam Cameron
Adam Cameron
zackster
05/08/2023, 10:21 AMAdam Cameron
inputBaseN
is working predictably / by design on CF.zackster
05/08/2023, 10:24 AMreturn Long.toString(Caster.toLongValue(number), (int) radix);
https://github.com/lucee/Lucee/blob/6.0/core/src/main/java/lucee/runtime/functions/displayFormatting/FormatBaseN.java#L33Adam Cameron
Adam Cameron
Mark Takata (Adobe)
05/08/2023, 3:37 PMseancorfield
build=> (Integer/toString -1234 16)
"-4d2"
build=> (Integer/toHexString -1234)
"fffffb2e"
seancorfield
> jshell
May 08, 2023 3:57:07 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
| Welcome to JShell -- Version 17.0.6
| For an introduction type: /help intro
jshell> Integer.toString(-1234, 16);
$1 ==> "-4d2"
jshell> Integer.toHexString(-1234);
$2 ==> "fffffb2e"
jshell>
Adam Cameron