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 3 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
2
(byte) b * b
makes abyte * int
, which will return anint
that you then attempt to assign to abyte
– ernest_k
37 mins 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
36 mins 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
32 mins 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 forbyte
s; so it has to useimul
– TiiJ7
26 mins ago
@Powerlord Yes,byte*byte
reurnsint
, that's why the second line needs a cast.
– ernest_k
25 mins ago
|
show 3 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 21 mins ago
Zlytherin
1,4841526
1,4841526
asked 39 mins ago
praveen padalapraveen padala
392
392
2
(byte) b * b
makes abyte * int
, which will return anint
that you then attempt to assign to abyte
– ernest_k
37 mins 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
36 mins 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
32 mins 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 forbyte
s; so it has to useimul
– TiiJ7
26 mins ago
@Powerlord Yes,byte*byte
reurnsint
, that's why the second line needs a cast.
– ernest_k
25 mins ago
|
show 3 more comments
2
(byte) b * b
makes abyte * int
, which will return anint
that you then attempt to assign to abyte
– ernest_k
37 mins 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
36 mins 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
32 mins 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 forbyte
s; so it has to useimul
– TiiJ7
26 mins ago
@Powerlord Yes,byte*byte
reurnsint
, that's why the second line needs a cast.
– ernest_k
25 mins ago
2
2
(byte) b * b
makes a byte * int
, which will return an int
that you then attempt to assign to a byte
– ernest_k
37 mins ago
(byte) b * b
makes a byte * int
, which will return an int
that you then attempt to assign to a byte
– ernest_k
37 mins 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
36 mins 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
36 mins 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
32 mins ago
@ernest_k I admit I haven't looked at the spec for a while, but does byte * byte always return an int?
– Powerlord
32 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 byte
s; so it has to use imul
– TiiJ7
26 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 byte
s; so it has to use imul
– TiiJ7
26 mins ago
@Powerlord Yes,
byte*byte
reurns int
, that's why the second line needs a cast.– ernest_k
25 mins ago
@Powerlord Yes,
byte*byte
reurns int
, that's why the second line needs a cast.– ernest_k
25 mins ago
|
show 3 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 byte
s promotes them to int
first, since there is no *
operator for byte
s. 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 toint
type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+
,−
,*
,/
,%
) islong
, then all values are converted tolong
type 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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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 byte
s promotes them to int
first, since there is no *
operator for byte
s. 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 byte
s promotes them to int
first, since there is no *
operator for byte
s. 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 byte
s promotes them to int
first, since there is no *
operator for byte
s. 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 byte
s promotes them to int
first, since there is no *
operator for byte
s. 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 24 mins ago
answered 37 mins ago
EranEran
282k37455541
282k37455541
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 33 mins ago
Zlytherin
1,4841526
1,4841526
answered 36 mins 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 toint
type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+
,−
,*
,/
,%
) islong
, then all values are converted tolong
type 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 toint
type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+
,−
,*
,/
,%
) islong
, then all values are converted tolong
type 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 toint
type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+
,−
,*
,/
,%
) islong
, then all values are converted tolong
type 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 toint
type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+
,−
,*
,/
,%
) islong
, then all values are converted tolong
type 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 21 mins ago
Zlytherin
1,4841526
1,4841526
answered 26 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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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
2
(byte) b * b
makes abyte * int
, which will return anint
that you then attempt to assign to abyte
– ernest_k
37 mins 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
36 mins 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
32 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 forbyte
s; so it has to useimul
– TiiJ7
26 mins ago
@Powerlord Yes,
byte*byte
reurnsint
, that's why the second line needs a cast.– ernest_k
25 mins ago