Type promotion in java












7















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?










share|improve this question




















  • 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











  • 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 for bytes; 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
















7















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?










share|improve this question




















  • 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











  • 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 for bytes; 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














7












7








7








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 21 mins ago









Zlytherin

1,4841526




1,4841526










asked 39 mins ago









praveen padalapraveen padala

392




392








  • 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











  • 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 for bytes; 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














  • 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











  • 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 for bytes; 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








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 bytes; 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 bytes; 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












3 Answers
3






active

oldest

votes


















10














(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:




  1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).



  2. 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.










share|improve this answer

































    2














    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






    share|improve this answer

































      1














      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 to int type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+, , *, /, %) is long, then all values are converted to long 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.






      share|improve this answer

























        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
        });


        }
        });














        draft saved

        draft discarded


















        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









        10














        (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:




        1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).



        2. 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.










        share|improve this answer






























          10














          (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:




          1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).



          2. 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.










          share|improve this answer




























            10












            10








            10







            (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:




            1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).



            2. 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.










            share|improve this answer















            (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:




            1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).



            2. 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.











            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 24 mins ago

























            answered 37 mins ago









            EranEran

            282k37455541




            282k37455541

























                2














                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






                share|improve this answer






























                  2














                  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






                  share|improve this answer




























                    2












                    2








                    2







                    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






                    share|improve this answer















                    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







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 33 mins ago









                    Zlytherin

                    1,4841526




                    1,4841526










                    answered 36 mins ago









                    Cyrus LeungCyrus Leung

                    444




                    444























                        1














                        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 to int type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+, , *, /, %) is long, then all values are converted to long 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.






                        share|improve this answer






























                          1














                          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 to int type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+, , *, /, %) is long, then all values are converted to long 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.






                          share|improve this answer




























                            1












                            1








                            1







                            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 to int type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+, , *, /, %) is long, then all values are converted to long 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.






                            share|improve this answer















                            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 to int type before the arithmetic operation in performed. However, if one of the values in an arithmetic operation (+, , *, /, %) is long, then all values are converted to long 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.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited 21 mins ago









                            Zlytherin

                            1,4841526




                            1,4841526










                            answered 26 mins ago









                            israelssisraelss

                            463




                            463






























                                draft saved

                                draft discarded




















































                                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.




                                draft saved


                                draft discarded














                                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





















































                                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







                                Popular posts from this blog

                                Polycentropodidae

                                Magento 2 Error message: Invalid state change requested

                                Paulmy