64

For certain hash functions in Java it would be nice to see the value as an unsigned integer (e.g. for comparison to other implementations) but Java supports only signed types. We can convert a signed int to an "unsigned" long as such:

public static final int BITS_PER_BYTE = 8;
public static long getUnsignedInt(int x) {
  ByteBuffer buf = ByteBuffer.allocate(Long.SIZE / BITS_PER_BYTE);
  buf.putInt(Integer.SIZE / BITS_PER_BYTE, x);
  return buf.getLong(0);
}
getUnsignedInt(-1); // => 4294967295

However, this solution seems like overkill for what we're really doing. Is there a more efficient way to achieve the same thing?

maerics
  • 151,642
  • 46
  • 269
  • 291

7 Answers7

109

Something like this?

int x = -1;
long y = x & 0x00000000ffffffffL;

Or am I missing something?

public static long getUnsignedInt(int x) {
    return x & 0x00000000ffffffffL;
}
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • 1
    @Paranaix I believe that would also work. It's been a while since I wrote this answer, so I think the reason why I padded with zeros was out of habit, since I do mostly C++ and the integer promotion rules there are more complicated with signed/unsigned types. – Mysticial Nov 29 '12 at 16:38
62

The standard way in Java 8 is Integer.toUnsignedLong(someInt), which is equivalent to @Mysticial's answer.

Community
  • 1
  • 1
superEb
  • 5,613
  • 35
  • 38
18

Guava provides UnsignedInts.toLong(int)...as well as a variety of other utilities on unsigned integers.

Iulian Popescu
  • 2,595
  • 4
  • 23
  • 31
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
9

You can use a function like

public static long getUnsignedInt(int x) {
    return x & (-1L >>> 32);
}

however in most cases you don't need to do this. You can use workarounds instead. e.g.

public static boolean unsignedEquals(int a, int b) {
    return a == b;
}

For more examples of workarounds for using unsigned values. Unsigned utility class

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Your getUnsignedInt function doesn't work. I made a serious error in my program as I didn't test it. :(( – user2707175 Jul 08 '14 at 20:08
  • getUnsignedInt appears to work as-is. `>>>` is correct. `>>` causes sign extension, and -1L right-shifted with sign extension any amount always results in a value with all ones. – Macil Oct 18 '17 at 17:48
  • getUnsignedInt works for me too, as-is. – Simon Savai Jan 06 '22 at 11:33
2

other solution.

public static long getUnsignedInt(int x) {
    if(x > 0) return x;
    long res = (long)(Math.pow(2, 32)) + x;
    return res;
}
lmatt
  • 197
  • 4
  • 5
    Math.pow is very expensive and calculated every time. By comparison `1l << 32` is fast and only calculated by the compiler. (And doesn't need to be cast to a long. – Peter Lawrey Mar 06 '12 at 08:23
  • Can you please give me some link or description on how these conversion work, m not able to understand it. – ManMohan Vyas Sep 28 '12 at 09:45
  • 1
    Because int is 32 bit and use two's complement to represent. You can check two's complement in wikipedia(http://en.wikipedia.org/wiki/Two's_complement) to get more details – lmatt Nov 14 '12 at 09:15
-2

Just my 2 cents here, but I think it's a good practice to use:

public static long getUnsignedInt(int x) { return x & (~0L); // ~ has precedence over & so no real need for brackets }

instead of:

return x & 0xFFFFFFFFL;

In this situation there's not your concern how many 'F's the mask has. It shall always work!

okoopat
  • 1
  • 1
  • 1
    This is completely wrong. The int is promoted to a long, and then you're masking it with a bit string of 64 ones which does nothing. The following prints -1 instead of 4294967295: int i = -1; long j = i & (~0L); System.out.println(j); – PBJ Apr 23 '15 at 20:02
  • yes it's my bad, I confused 0xFFFFFFFFL with ~0L which obvious it's not the case – okoopat Jun 17 '15 at 12:10
-4
long abs(int num){
    return num < 0 ? num * -1 : num;
}
user2207488
  • 36
  • 1
  • 2
  • please read about two's complement (https://en.wikipedia.org/wiki/Two%27s_complement) which describes how signed numbers are usually represented. You cant just take absolute value for resolving that issue (http://tadej.me/twos-complement-and-absolute-values/). – Stepan Pogosyan Mar 18 '18 at 21:28