Unsigned int (primitive) and Integer (Object) usage in Java
Asked Answered
M

3

6

I'm following the Java tutorial on Primitive Data Types. Early on, it states that

In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2^32-1. Use the Integer class to use int data type as an unsigned integer.

What I'm understanding from this quote is that I can now store up to 2^32-1 as an int as long as I use the Integer wrapper object rather than the int primitive data type. But when I tried this out, my compiler is complaining that the value I'm using is too large, 2^31. I've tried this using both the primitive data type and Object.

Integer integerObjectLarge = 2147483648; //2^31
int integerPrimitiveLarge = 2147483648; //2^31

How exactly do I use an int/Integer to store unsigned value, such as 2^31?

Misfire answered 25/7, 2014 at 20:47 Comment(6)
Can you provide a source for the quote?Yttria
linkMisfire
docs.oracle.com/javase/tutorial/java/nutsandbolts/…Eldrid
Possibly silly question -> Do you have J8 installed?Knell
Correct me if I'm wrong, but it does say -1, which 2147483647 doesn't give any problemsHarbird
Yes, I do. Double most recent update, and double checked it.Misfire
S
2

But when I tried this out, my compiler is complaining that the value I'm using is too large, 2^31.

You have an error because the literal 2147483648 is syntactically invalid.


How exactly do I use an int/Integer to store unsigned value, such as 2^31?

You can still perform unsigned arithmetic using the new methods of the Integer class, just don't use invalid literals:

int n = 2147483647 + 1;  // 2^31

System.out.println(Integer.toUnsignedString(n));  // treat int as unsigned
System.out.println(Integer.toString(n));          // treat int as signed
2147483648
-2147483648

What I'm understanding from this quote is that I can now store up to 2^32-1 as an int as long as I use the Integer wrapper object rather than the int primitive data type.

You can store the unsigned int using the primitive type int, but using the value as an unsigned type requires you to use the utility methods of Integer, as can be seen above.

Somatic answered 25/7, 2014 at 20:54 Comment(0)
B
9

I don't think Java has added a true unsigned 32-bit int type. The only thing that's changed is that the Integer class now contains some methods that will treat a 32-bit integer(s) as an unsigned 32-bit integer. See compareUnsigned, divideUnsigned, parseUnsignedInt, and several others in the javadoc for Integer. Long has some new methods too.

But basically, if you store the bit pattern (for example) 10001000_11110000_10010110_11000010 in an int, there's nothing in the int that says "This is an unsigned integer" or "This is a signed integer". It depends on what methods you use to work with it.

Bruton answered 25/7, 2014 at 20:55 Comment(3)
Yeah, the Java language folks continue their tradition of obfuscating rather than elucidating.Dovetailed
I can understand why they might not have wanted to add a new primitive type. But it just occurred to me that they could have added a new literal suffix without making anything else backward-incompatible or changing any other language rules, so that, say, 2147483649U would be equivalent to the int -2147483647.Bruton
Yep, could have added the suffix (though it might require minor JVM changes). And I suppose if you use L then you'd need a cast to keep the compiler from objecting.Dovetailed
S
2

But when I tried this out, my compiler is complaining that the value I'm using is too large, 2^31.

You have an error because the literal 2147483648 is syntactically invalid.


How exactly do I use an int/Integer to store unsigned value, such as 2^31?

You can still perform unsigned arithmetic using the new methods of the Integer class, just don't use invalid literals:

int n = 2147483647 + 1;  // 2^31

System.out.println(Integer.toUnsignedString(n));  // treat int as unsigned
System.out.println(Integer.toString(n));          // treat int as signed
2147483648
-2147483648

What I'm understanding from this quote is that I can now store up to 2^32-1 as an int as long as I use the Integer wrapper object rather than the int primitive data type.

You can store the unsigned int using the primitive type int, but using the value as an unsigned type requires you to use the utility methods of Integer, as can be seen above.

Somatic answered 25/7, 2014 at 20:54 Comment(0)
H
2

You've always been able to store "unsigned" integer literals by using hex:

 int x = 0xffffffff;
 // or any value >= 0x80000000;

This is because, for all practical purposes, the compiler thinks these are "signed".

You still can't assign a decimal value > 2^31 - 1 because it would create all sorts of backwards compatibility issues if this were suddenly allowed.

Hedelman answered 25/7, 2014 at 21:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.