Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Java equivalent of __builtin_clz? [closed]

Tags:

java

c

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


2 Answers

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).

like image 139
rzwitserloot Avatar answered Nov 30 '25 17:11

rzwitserloot


False alarm: Caused by a typo - I actually needed __builtin_ctzll instead, which now makes a lot more sense.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!