Signed And Unsigned Arithmetic Operators in Java
A brief introduction to JAVA
Java makes writing, compiling, and debugging programs easy. It makes it easier to write reusable code and modular programs.
The development of the Java programming language was primarily focused on making it portable, simple, and secure. Apart from that, the language has a variety of positive qualities that contribute to its popularity.
Operators in JAVA
Variables and values are manipulated using operators. Examples include addition, comparison, and other comparable operations.
In JAVA, you can use a variety of operators, such as:
Common mathematical activities are carried out using arithmetic operators.
Variables are assigned values using assignment operators.
To compare two values, comparison operators are employed.
The logic between variables or values is determined using logical operators.
The ternary operator is a conditional operator with three parts.
The types of unary operators only need one operand to accomplish any operation.
Individual bits of a number are manipulated using bitwise operators.
Signed and Unsigned Integers:
Integers containing a "+" or "-" sign are known as signed integers. If n bits are used to represent a signed binary integer number, one bit will be used to represent the number's sign, and the remaining (n - 1) bits will be used to represent the number's magnitude.
Temperatures, for example, can range from positive (38 degrees C) to negative (-38 degrees C) (say -11 degree C).
The following format can be used to represent signed binary numbers:
Magnitude and Sign: In this case, the binary number's MSB reflects the number's sign, while the other bits represent its magnitude. Assuming a word size of 4 bits, for example:
One's complement: In this method, the MSB denotes the number's sign, while the other bits are the number's 1's complement (i.e., invert the bits from 0 to 1 and vice versa). Assuming a word size of 4 bits, for example:
Two's complement: In this method, the MSB represents the number's sign, while the other bits are 2's complement (i.e. add 1 to the number's 1's complement). Assuming a word size of 4 bits, for example:
Shift operators in Java:
At times when speed is more important that code readability, unsigned integers are preferred for primitive int values for efficiency. So, unsigned integers are especially useful with binary context, like representing memory contents, bit shifting, bit masking, and in other numeric computational contexts like cryptography.
The shift operator is a sort of operator that is used to manipulate bits in data. The shift operators are used to move the bits of their first operand from right to left or left to right. Right-shift operator, unsigned right-shift operator, and left-shift operator are the three types of shift operators accessible in Java. Java does not allow unsigned left shift.
The Right-shift operator is a type of operator that moves the bits of a shift-expression to the right. According to the number of positions supplied in the additive-expression, the right-shift operator moves the bits pattern to the right.
Another sort of operator is the Left-shift operator, which is used to shift the bits of a shift expression to the left. According to the number of positions supplied in the additive-expression, the left-shift operator moves the bits pattern to the left.
The unsigned right-shift operator is a form of right-shift operator that fills the trailing location without using the sign bit. The trialing position is always filled by 0 when the unsigned right-shift operator is used.
Java 8 Unsigned Arithmetic Support:
The JDK now supports unsigned arithmetic in version 8. This feature was supplied through the Unsigned Integer API, which largely consists of static methods in the Integer and Long classes.
The Unsigned Integer API in Java 8 now enables unsigned integer arithmetic. The majority of this API's components are static methods in the Integer and Long classes.
Comparison
To compare unsigned values, the Integer class has a method called compareUnsigned. This approach ignores the sign bit and treats all binary values as unsigned.
Let's start with two numbers at the int data type's edges:
int positive = Integer.MAX_VALUE;
int negative = Integer.MIN_VALUE;
When we examine these numbers as signed values, we can see that positive is clearly superior to negative:
int signedComparison = Integer.compare(positive, negative);
assertEquals(1, signedComparison);
When comparing integers as unsigned values, the left-most bit, rather than the sign bit, is considered the most significant bit. As a result, the outcome is different, with positive values being smaller than negative values:
int unsignedComparison = Integer.compareUnsigned(positive, negative);
assertEquals(-1, unsignedComparison);
If we look at the binary form of those integers, it should become clearer:
MAX_VALUE → 0111_1111…1111
MIN_VALUE → 1000_0000…0000
When the left-most bit is a regular value bit, MIN VALUE is one unit larger than MAX VALUE in the binary system. As a consequence of this test, the following conclusions can be drawn:
assertEquals(negative, positive + 1);
Division and Modulo
Like the comparison operation, the unsigned division and modulo operations treat all bits as value bits. As a result, the quotients and remainders differ when these operations are performed on signed and unsigned numbers:
int positive = Integer.MAX_VALUE;
int negative = Integer.MIN_VALUE;
assertEquals(-1, negative / positive);
assertEquals(1, Integer.divideUnsigned(negative, positive));
assertEquals(-1, negative % positive);
assertEquals(1, Integer.remainderUnsigned(negative, positive));
Parsing
The text argument can represent a number bigger than MAX VALUE when parsing a String with the parseUnsignedInt function.
The parseInt method can only handle textual representations of numbers from MIN VALUE to MAX VALUE, therefore a huge value like that can't be parsed.
The parsing results are verified in the following test case:
Throwable thrown = catchThrowable(() -> Integer.parseInt("2147483648"));
assertThat(thrown).isInstanceOf(NumberFormatException.class);
assertEquals(Integer.MAX_VALUE + 1, Integer.parseUnsignedInt("2147483648"));
The parseUnsignedInt method can parse a string showing a number greater than MAX VALUE, but it cannot parse a string indicating a negative value.
Formatting
Similar to parsing, when formatting a number, an unsigned operation regards all bits as value bits. Consequently, we can produce the textual representation of a number about twice as large as MAX_VALUE.
The following test case confirms the formatting result of MIN_VALUE in both cases — signed and unsigned:
String signedString = Integer.toString(Integer.MIN_VALUE);
assertEquals("-2147483648", signedString);
String unsignedString = Integer.toUnsignedString(Integer.MIN_VALUE);
assertEquals("2147483648", unsignedString);
Operators in java
Signed Left Shift Operators
The left shift operator shifts all bits towards the left by a certain number of specified bits. It is denoted by <<.
Example :-
Code
Signed Right Shift Operators
The signed right shift operator shifts all bits towards the right by a certain number of specified bits. It is denoted by >>.
Example :-
Output:
Unsigned Right shift Operators
Java also provides an unsigned right shift. It is denoted by >>>.
Example :-
Output:
Interesting one! Examples made it more easy
ReplyDeleteLoved The Way You Have Written This Practical Blog With full Of knowledge and enthusiasm ...
ReplyDeleteGreat Work Team 🌻
Great read! 👏👏
ReplyDeletegood content, Great explanation and helpful for understanding
ReplyDeleteVery nice, Informative. Great work guys.
ReplyDeletegreat content, covered all povs.
ReplyDeleteInformative
ReplyDeleteInformative! Keep it up
ReplyDeleteInformative content 👍🏻
ReplyDeleteNice work
ReplyDeleteGreat content and informative
ReplyDelete"can u explain the assertEquals of junit Api"?
ReplyDeleteBasically, the asserEquals method of JUnit API checks if two objects/primitives are equal, and it relies on equals method of Object class. You can optionally mention the failure msg too. Also the other utilities of this are helpful when you do unit testing using junit.
DeleteHope you got the point! Thanks