A narrowing conversion is when putting a data type that can hold a bigger value into a data type that can hold at max a lesser value.
long l = 4L;
int i = (int)l;
However I don't understand why a short into a char is a narrowing conversion but I've the intuition it is related to signed/unsigned of those two datatypes but I can't explain why.
short s = 4; // short max value is 32767
char c = (char)s; // char max value is 65535
It looks like it would be a widening conversion or at the very least neither narrowing neither widening since they are both 16 bits and can hold the same number of values.
System.out.println((int)Character.MIN_VALUE); //0
System.out.println((int)Character.MAX_VALUE); //65535
System.out.println(Short.MIN_VALUE); //-32768
System.out.println(Short.MAX_VALUE); //32767
//65535 = 32768+32767
This is because a short
is capable of holding negative values while char
isn't as you might have seen from Character.MIN_VALUE
. Let me give a few examples.
short s = -124;
char c = 124; // OK, no compile time error
char d = -124; // NOT OK, compile time error since char cannot hold -ve values
char e = s; // NOT OK, compile time error since a short might have -ve values which char won't be able to hold
char f = (char)s; // OK, type casting. The negative number -124 gets converted to 65412 so that char can hold it
System.out.println((short)f); // -124, gets converted back to a number short can hold because short won't be able to hold 65412
System.out.println((int)f); // 65412, gets converted to 65412 because int can easily hold it.
A (negative) number -n
when cast to char
, becomes 2^16-n
. So, -124
becomes2^16-124 = 65412
I hope this helps.
The point of narrowing isn't about the bit size, but that some values cannot be properly represented in the new type.
As you have shown in the last piece of code, Short.MIN_VALUE < Character.MIN_VALUE
, i.e. some short
values cannot be represented in char
.
Since you can't use char
to faithfully represent negative numbers (the cast will cause a negative number be represented by its 2's complement, which isn't the same number), we consider the cast "loses information" and thus narrowing.
From the Java Language Specification, §5.1.3:
22 specific conversions on primitive types are called the narrowing primitive conversions:
short
tobyte
orchar
char
tobyte
orshort
- ...
A narrowing primitive conversion may lose information about the overall magnitude of a numeric value and may also lose precision and range.
...
A narrowing conversion of a signed integer to an integral type
T
simply discards all but the n lowest order bits, where n is the number of bits used to represent typeT
. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.A narrowing conversion of a
char
to an integral typeT
likewise simply discards all but the n lowest order bits, where n is the number of bits used to represent typeT
. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the resulting value to be a negative number, even though chars represent 16-bit unsigned integer values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With