Why doesn't Java support unsigned ints?
This is from an interview with Gosling and others, about simplicity:
Gosling: For me as a language designer, which I don't really count myself as these days, what "simple" really ended up meaning was could I expect J. Random Developer to hold the spec in his head. That definition says that, for instance, Java isn't -- and in fact a lot of these languages end up with a lot of corner cases, things that nobody really understands. Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is. Things like that made C complex. The language part of Java is, I think, pretty simple. The libraries you have to look up.
Declaring an unsigned int in Java
Java does not have a datatype for unsigned integers.
You can define a long
instead of an int
if you need to store large values.
You can also use a signed integer as if it were unsigned. The benefit of two's complement representation is that most operations (such as addition, subtraction, multiplication, and left shift) are identical on a binary level for signed and unsigned integers. A few operations (division, right shift, comparison, and casting), however, are different. As of Java SE 8, new methods in the Integer
class allow you to fully use the int
data type to perform unsigned arithmetic:
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. Static methods like
compareUnsigned
,divideUnsigned
etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
Note that int
variables are still signed when declared but unsigned arithmetic is now possible by using those methods in the Integer
class.
Signed and unsigned data types in java
Java only supports signed types (except char
) because it was assumed that one type was simpler for beginners to understand than having two types for each size. In C it was perceived to be a source of error so support for unsigned types was not included.
So the designers picked four sizes
byte
, 8 bitshort
, 16 bitint
, 32 bitlong
, 64 bit.
and to keep things consistent they were all signed just like float
and double
However a signed byte is rarely very useful and given they allowed unsigned 16-bit char
having an unsigned byte
might have made more sense.
Where this doesn't work so well is when you have to interact with systems which use unsigned integer types. This can be source of confusion and to which type to use instead because often it doesn't make any difference. Java 8 will have operations to support unsigned types as well. These are added to the wrapper classes like Integer
and Long
How to use the unsigned Integer in Java 8 and Java 9?
Per the documentation you posted, and this blog post - there's no difference when declaring the primitive between an unsigned int/long and a signed one. The "new support" is the addition of the static methods in the Integer and Long classes, e.g. Integer.divideUnsigned. If you're not using those methods, your "unsigned" long above 2^63-1 is just a plain old long with a negative value.
From a quick skim, it doesn't look like there's a way to declare integer constants in the range outside of +/- 2^31-1, or +/- 2^63-1 for longs. You would have to manually compute the negative value corresponding to your out-of-range positive value.
Why DataInput interface in Java doesn't have readUnsignedInt method
DataInput/DataOutput has a method for each of the primitives and String.
unsigned int
is not a primitive but you can do the following since it was added.
long a = dis.readInt() & 0xFFFF_FFFFL;
dos.writeInt((int) a);
Why this interface doesn't have a readUnsignedInt method that would return long?
I assume the original designers didn't think you need one or they would have added an unsigned int
type.
Is there any particular reason?
There is so many things you could add (and in my library I have added because I think they are useful) but the designers seemed to believe less is more.
Why doesn't Kotlin support unsigned integers?
Unsigned counterparts of Byte
, Short
, Int
and Long
do exist in Beta since Kotlin 1.3 and are stable as of Kotlin 1.5:
From the docs:
kotlin.UByte
: an unsigned 8-bit integer, ranges from 0 to 255kotlin.UShort
: an unsigned 16-bit integer, ranges from 0 to 65535kotlin.UInt
: an unsigned 32-bit integer, ranges from 0 to 2^32 - 1kotlin.ULong
: an unsigned 64-bit integer, ranges from 0 to 2^64 - 1
Usage
// You can define unsigned types using literal suffixes
val uint = 42u
// You can convert signed types to unsigned and vice versa via stdlib extensions:
val int = uint.toInt()
val uint = int.toUInt()
Why doesn't .NET use unsigned integer types for things like DateTime.Month and DateTime.Year?
To quote "Language Independence and Language-Independent Components"
The .NET Framework is language independent. This means that, as a developer, you can develop in one of the many languages that target the .NET Framework, such as C#, C++/CLI, Eiffel, F#, IronPython, IronRuby, PowerBuilder, Visual Basic, Visual COBOL, and Windows PowerShell. You can access the types and members of class libraries developed for the .NET Framework without having to know the language in which they were originally written and without having to follow any of the original language's conventions. If you are a component developer, your component can be accessed by any .NET Framework app regardless of its language.
Not all languages support unsigned integers, so because of that using unsigned integers in public or protected methods makes your code non CLS compliant. You are allowed to use them on private and internal members, just not on public or protected ones. Because of this the .NET framework tries to make all of it's public methods and members CLS compliant so they can be used from any language.
Java8 unsigned arithmetic
If you're referring to
(Long.compareUnsigned(l, Long.MAX_VALUE*2) < 0)
l
reaches
-9223372036854775808
unsigned it is
9223372036854775808
and
Long.MAX_VALUE*2
is
18446744073709551614
So l
is smaller than Long.MAX_VALUE*2
in the unsigned world.
Assuming you're asking about the 0's
0
0
0
...
0
the problem (if you see it that way) is that, for long
(other numerical primitives), the first bit is the sign bit.
so
10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
is
-9223372036854775808
When you do
-9223372036854775808 + -9223372036854775808
you underflow (overflow?) since
10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+ 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
is
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
which is 0. On later loop iterations, 0 + 0
remains 0
.
Is Java's lack of unsigned primitive types a characteristic of Java the platform or Java the language?
Java Bytecode Specification only defines signed types:
The integral types are byte, short, int, and long, whose values are
8-bit, 16-bit, 32-bit, and 64-bit signed two's-complement integers
But a language implemented on top of the JVM can probably add an unsigned type at the syntactic level and just handle the conversion at the compilation stage.
Related Topics
Maven Modules + Building a Single Specific Module
Handling Exceptions from Java Executorservice Tasks
What Is the Meaning of the Cascadetype.All for a @Manytoone JPA Association
Nullpointerexception in Collectors.Tomap with Null Entry Values
When to Use Comparable and Comparator
Java List.Contains(Object with Field Value Equal to X)
How to Convert Milliseconds to "Hh:Mm:Ss" Format
Why to Use Interfaces, Multiple Inheritance VS Interfaces, Benefits of Interfaces
What Is the Use of Interface Constants
What Does Java Option -Xmx Stand For
How to Set Output Stream to Textarea
Javafx Controller Class Not Working
Java Thread.Sleep Puts Swing UI to Sleep Too
Is It a Bad Practice to Catch Throwable
Embedding Java Applet into .HTML File
Verification of Element in Viewport in Selenium