Type promotion in java
I have a problem with the below Java statements:
byte b = 10;
byte r = (byte) (b * b);// giving correct result
byte r = (byte) b * b;// giving error " POSSIBLE LOSS OF PRECISION"
Why is it mandatory to give parentheses to b * b?
java
|
show 5 more comments
I have a problem with the below Java statements:
byte b = 10;
byte r = (byte) (b * b);// giving correct result
byte r = (byte) b * b;// giving error " POSSIBLE LOSS OF PRECISION"
Why is it mandatory to give parentheses to b * b?
java
4
(byte) b * bmakes abyte * int, which will return anintthat you then attempt to assign to abyte
– ernest_k
1 hour ago
Interestingly if you were doingb *= b;, that would compile as in that case the language specification requires an implicit casting to the original type.
– Gábor Bakos
1 hour ago
1
@ernest_k I admit I haven't looked at the spec for a while, but does byte * byte always return an int?
– Powerlord
1 hour ago
@Powerlord It does indeed always produce anint. This is the only spec I found for it. If you look at the bytecode list, you'll also see that there are no instructions for arithmetic forbytes; so it has to useimul
– TiiJ7
54 mins ago
1
Fun fact: makingbfinalallows it to compile.
– Andy Turner
37 mins ago
|
show 5 more comments
I have a problem with the below Java statements:
byte b = 10;
byte r = (byte) (b * b);// giving correct result
byte r = (byte) b * b;// giving error " POSSIBLE LOSS OF PRECISION"
Why is it mandatory to give parentheses to b * b?
java
I have a problem with the below Java statements:
byte b = 10;
byte r = (byte) (b * b);// giving correct result
byte r = (byte) b * b;// giving error " POSSIBLE LOSS OF PRECISION"
Why is it mandatory to give parentheses to b * b?
java
java
edited 49 mins ago
Zlytherin
1,4861526
1,4861526
asked 1 hour ago
praveen padalapraveen padala
392
392
4
(byte) b * bmakes abyte * int, which will return anintthat you then attempt to assign to abyte
– ernest_k
1 hour ago
Interestingly if you were doingb *= b;, that would compile as in that case the language specification requires an implicit casting to the original type.
– Gábor Bakos
1 hour ago
1
@ernest_k I admit I haven't looked at the spec for a while, but does byte * byte always return an int?
– Powerlord
1 hour ago
@Powerlord It does indeed always produce anint. This is the only spec I found for it. If you look at the bytecode list, you'll also see that there are no instructions for arithmetic forbytes; so it has to useimul
– TiiJ7
54 mins ago
1
Fun fact: makingbfinalallows it to compile.
– Andy Turner
37 mins ago
|
show 5 more comments
4
(byte) b * bmakes abyte * int, which will return anintthat you then attempt to assign to abyte
– ernest_k
1 hour ago
Interestingly if you were doingb *= b;, that would compile as in that case the language specification requires an implicit casting to the original type.
– Gábor Bakos
1 hour ago
1
@ernest_k I admit I haven't looked at the spec for a while, but does byte * byte always return an int?
– Powerlord
1 hour ago
@Powerlord It does indeed always produce anint. This is the only spec I found for it. If you look at the bytecode list, you'll also see that there are no instructions for arithmetic forbytes; so it has to useimul
– TiiJ7
54 mins ago
1
Fun fact: makingbfinalallows it to compile.
– Andy Turner
37 mins ago
4
4
(byte) b * b makes a byte * int, which will return an int that you then attempt to assign to a byte– ernest_k
1 hour ago
(byte) b * b makes a byte * int, which will return an int that you then attempt to assign to a byte– ernest_k
1 hour ago
Interestingly if you were doing
b *= b;, that would compile as in that case the language specification requires an implicit casting to the original type.– Gábor Bakos
1 hour ago
Interestingly if you were doing
b *= b;, that would compile as in that case the language specification requires an implicit casting to the original type.– Gábor Bakos
1 hour ago
1
1
@ernest_k I admit I haven't looked at the spec for a while, but does byte * byte always return an int?
– Powerlord
1 hour ago
@ernest_k I admit I haven't looked at the spec for a while, but does byte * byte always return an int?
– Powerlord
1 hour ago
@Powerlord It does indeed always produce an
int. This is the only spec I found for it. If you look at the bytecode list, you'll also see that there are no instructions for arithmetic for bytes; so it has to use imul– TiiJ7
54 mins ago
@Powerlord It does indeed always produce an
int. This is the only spec I found for it. If you look at the bytecode list, you'll also see that there are no instructions for arithmetic for bytes; so it has to use imul– TiiJ7
54 mins ago
1
1
Fun fact: making
b final allows it to compile.– Andy Turner
37 mins ago
Fun fact: making
b final allows it to compile.– Andy Turner
37 mins ago
|
show 5 more comments
3 Answers
3
active
oldest
votes
(byte) b * b casts the value of the first b to byte (which is redundant since it was already byte), and multiples it by the value of the second b. Multiplying two bytes promotes them to int first, since there is no * operator for bytes. Therefore the result is int, and cannot be assigned to a byte variable.
On the other hand, (byte)(b * b) casts the int multiplication result to byte, which can be assigned to a byte variable.
This is covered in the JLS in 5.6.2. Binary Numeric Promotion:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
add a comment |
Casting problem
byte r = (byte) (b * b);
It casts the (byte) type to the result of (b * b)
byte r = (byte) b * b;
It casts the (byte) type to the first b only, therefore it will become ((byte) b) * b
add a comment |
By the precedence rule you are casting only the first b to byte instead of the whole result.
And Java follow some rules, as you can see here
All integer values (byte, short and int) in an arithmetic operations (
+,−,*,/,%) are converted tointtype before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+,−,*,/,%) islong, then all values are converted tolongtype before the arithmetic operation in performed.
So, by just casting the first b you are doing this:
byte = byte * integer
Hence:
byte = integer
Thus, raised error.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54212716%2ftype-promotion-in-java%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
(byte) b * b casts the value of the first b to byte (which is redundant since it was already byte), and multiples it by the value of the second b. Multiplying two bytes promotes them to int first, since there is no * operator for bytes. Therefore the result is int, and cannot be assigned to a byte variable.
On the other hand, (byte)(b * b) casts the int multiplication result to byte, which can be assigned to a byte variable.
This is covered in the JLS in 5.6.2. Binary Numeric Promotion:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
add a comment |
(byte) b * b casts the value of the first b to byte (which is redundant since it was already byte), and multiples it by the value of the second b. Multiplying two bytes promotes them to int first, since there is no * operator for bytes. Therefore the result is int, and cannot be assigned to a byte variable.
On the other hand, (byte)(b * b) casts the int multiplication result to byte, which can be assigned to a byte variable.
This is covered in the JLS in 5.6.2. Binary Numeric Promotion:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
add a comment |
(byte) b * b casts the value of the first b to byte (which is redundant since it was already byte), and multiples it by the value of the second b. Multiplying two bytes promotes them to int first, since there is no * operator for bytes. Therefore the result is int, and cannot be assigned to a byte variable.
On the other hand, (byte)(b * b) casts the int multiplication result to byte, which can be assigned to a byte variable.
This is covered in the JLS in 5.6.2. Binary Numeric Promotion:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
(byte) b * b casts the value of the first b to byte (which is redundant since it was already byte), and multiples it by the value of the second b. Multiplying two bytes promotes them to int first, since there is no * operator for bytes. Therefore the result is int, and cannot be assigned to a byte variable.
On the other hand, (byte)(b * b) casts the int multiplication result to byte, which can be assigned to a byte variable.
This is covered in the JLS in 5.6.2. Binary Numeric Promotion:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
edited 52 mins ago
answered 1 hour ago
EranEran
282k37455542
282k37455542
add a comment |
add a comment |
Casting problem
byte r = (byte) (b * b);
It casts the (byte) type to the result of (b * b)
byte r = (byte) b * b;
It casts the (byte) type to the first b only, therefore it will become ((byte) b) * b
add a comment |
Casting problem
byte r = (byte) (b * b);
It casts the (byte) type to the result of (b * b)
byte r = (byte) b * b;
It casts the (byte) type to the first b only, therefore it will become ((byte) b) * b
add a comment |
Casting problem
byte r = (byte) (b * b);
It casts the (byte) type to the result of (b * b)
byte r = (byte) b * b;
It casts the (byte) type to the first b only, therefore it will become ((byte) b) * b
Casting problem
byte r = (byte) (b * b);
It casts the (byte) type to the result of (b * b)
byte r = (byte) b * b;
It casts the (byte) type to the first b only, therefore it will become ((byte) b) * b
edited 1 hour ago
Zlytherin
1,4861526
1,4861526
answered 1 hour ago
Cyrus LeungCyrus Leung
444
444
add a comment |
add a comment |
By the precedence rule you are casting only the first b to byte instead of the whole result.
And Java follow some rules, as you can see here
All integer values (byte, short and int) in an arithmetic operations (
+,−,*,/,%) are converted tointtype before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+,−,*,/,%) islong, then all values are converted tolongtype before the arithmetic operation in performed.
So, by just casting the first b you are doing this:
byte = byte * integer
Hence:
byte = integer
Thus, raised error.
add a comment |
By the precedence rule you are casting only the first b to byte instead of the whole result.
And Java follow some rules, as you can see here
All integer values (byte, short and int) in an arithmetic operations (
+,−,*,/,%) are converted tointtype before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+,−,*,/,%) islong, then all values are converted tolongtype before the arithmetic operation in performed.
So, by just casting the first b you are doing this:
byte = byte * integer
Hence:
byte = integer
Thus, raised error.
add a comment |
By the precedence rule you are casting only the first b to byte instead of the whole result.
And Java follow some rules, as you can see here
All integer values (byte, short and int) in an arithmetic operations (
+,−,*,/,%) are converted tointtype before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+,−,*,/,%) islong, then all values are converted tolongtype before the arithmetic operation in performed.
So, by just casting the first b you are doing this:
byte = byte * integer
Hence:
byte = integer
Thus, raised error.
By the precedence rule you are casting only the first b to byte instead of the whole result.
And Java follow some rules, as you can see here
All integer values (byte, short and int) in an arithmetic operations (
+,−,*,/,%) are converted tointtype before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+,−,*,/,%) islong, then all values are converted tolongtype before the arithmetic operation in performed.
So, by just casting the first b you are doing this:
byte = byte * integer
Hence:
byte = integer
Thus, raised error.
edited 50 mins ago
Zlytherin
1,4861526
1,4861526
answered 54 mins ago
israelssisraelss
463
463
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54212716%2ftype-promotion-in-java%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
(byte) b * bmakes abyte * int, which will return anintthat you then attempt to assign to abyte– ernest_k
1 hour ago
Interestingly if you were doing
b *= b;, that would compile as in that case the language specification requires an implicit casting to the original type.– Gábor Bakos
1 hour ago
1
@ernest_k I admit I haven't looked at the spec for a while, but does byte * byte always return an int?
– Powerlord
1 hour ago
@Powerlord It does indeed always produce an
int. This is the only spec I found for it. If you look at the bytecode list, you'll also see that there are no instructions for arithmetic forbytes; so it has to useimul– TiiJ7
54 mins ago
1
Fun fact: making
bfinalallows it to compile.– Andy Turner
37 mins ago