I need a Java equivalent of __builtin_clz.
It feels like the answer should be Long.numberOfLeadingZeros but they return completely different answers.
I'm starting to wonder if there is a low-level reason for this - maybe endianness? or some quirk of unsigned?
EDIT: False alarm. This is purely caused by a typo - the original code actually calls __builtin_ctzll and is matched by Long.numberOfTrailingZeros
Long.numberOfLeadingZeros is precisely correct.
The fact that you get different answers is because C. C does not define what int means. Therefore, the answer that __builtin_clz(a) gives is different on every box you run it on: It depends on the bit width of int, and as per the C standard, the bit width of an int is whatever is convenient for the system you're compiling for. If it's 32-bit (that's a very common bit width), __builtin_clz(16) would return 27. If it's 64-bit (also quite common), __builtin_clz(16) would return 59.
Java doesn't generally 'do' the whole undefined thing. In java, unlike C, int is a signed 32-bit number. No matter what VM, version, platform, or OS you're running it on or compiled it on. Similarly, a long is signed 64-bit.
Nevertheless, Long.numberOfLeadingZeroes effectively treats the number as unsigned just like __builtin_clz does: That means __builtin_clz(x), where x is a negative number, always returns 0 (or should, according to the C spec), and Long.numberOfLeadingZeros does the exact same thing: Always returns 0 (no leading zero bits), for negative numbers.
In other words, on 64-bit systems, __builtin_clz(x) is matched perfectly by Long.numberOfLeadingZeros(x) in java. On 32-bit systems, __builtin_clz(x) returns 32 less than that (__builtin_clz(16) on 64-bit is 59, but on 32-bit, it's 27), and in java, you'd have to use Integer.numberOfLeadingZeros() instead. Integer.numberOfLeadingZeros(16) returns 27. Just like __builtin_clz(16) would , if targeting a system where int is defined as 32-bit (it would be, if targeting 32-bit processors).
False alarm: Caused by a typo - I actually needed __builtin_ctzll instead, which now makes a lot more sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With