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




















  • 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











  • 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 for bytes; so it has to use imul

    – TiiJ7
    54 mins ago






  • 1





    Fun fact: making b final allows it to compile.

    – Andy Turner
    37 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




















  • 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











  • 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 for bytes; so it has to use imul

    – TiiJ7
    54 mins ago






  • 1





    Fun fact: making b final allows it to compile.

    – Andy Turner
    37 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 49 mins ago









Zlytherin

1,4861526




1,4861526










asked 1 hour ago









praveen padalapraveen padala

392




392








  • 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











  • 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 for bytes; so it has to use imul

    – TiiJ7
    54 mins ago






  • 1





    Fun fact: making b final allows it to compile.

    – Andy Turner
    37 mins ago














  • 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











  • 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 for bytes; so it has to use imul

    – TiiJ7
    54 mins ago






  • 1





    Fun fact: making b final allows 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












3 Answers
3






active

oldest

votes


















11














(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









        11














        (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






























          11














          (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




























            11












            11








            11







            (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 52 mins ago

























            answered 1 hour ago









            EranEran

            282k37455542




            282k37455542

























                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 1 hour ago









                    Zlytherin

                    1,4861526




                    1,4861526










                    answered 1 hour 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 50 mins ago









                            Zlytherin

                            1,4861526




                            1,4861526










                            answered 54 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

                                Wolfgang Unzicker

                                Unua mondmilito

                                Schloss Hohenburg (Lenggries)