If a negative integer summed with a greater unsiged integer is promoted to unsigned int?












7















After getting advised to read "C++ Primer 5 ed by Stanley B. Lipman" I don't understand this:



Page 66. "Expressions Involving Unsigned Types"



unsigned u = 10;
int i = -42;
std::cout << i + i << std::endl; // prints -84
std::cout << u + i << std::endl; // if 32-bit ints, prints 4294967264


He said:




In the second expression, the int value -42 is converted to unsigned before the addition is done. Converting a negative number to unsigned behaves exactly as if we had attempted to assign that negative value to an unsigned object. The value “wraps around” as described above.




But if I do something like this:



unsigned u = 42;
int i = -10;
std::cout << u + i << std::endl; // Why the result is 32?


As you can see -10 is not converted to unsigned int. Does this mean a comparison occurs before promoting a signed integer to an unsigned integer?










share|improve this question




















  • 6





    As you can see -10 is not converted to unsigned int. It is.

    – tkausl
    1 hour ago











  • Google about binary numbers and the way they are represented, in particular signedness. Then all shall become clear.

    – DeiDei
    1 hour ago
















7















After getting advised to read "C++ Primer 5 ed by Stanley B. Lipman" I don't understand this:



Page 66. "Expressions Involving Unsigned Types"



unsigned u = 10;
int i = -42;
std::cout << i + i << std::endl; // prints -84
std::cout << u + i << std::endl; // if 32-bit ints, prints 4294967264


He said:




In the second expression, the int value -42 is converted to unsigned before the addition is done. Converting a negative number to unsigned behaves exactly as if we had attempted to assign that negative value to an unsigned object. The value “wraps around” as described above.




But if I do something like this:



unsigned u = 42;
int i = -10;
std::cout << u + i << std::endl; // Why the result is 32?


As you can see -10 is not converted to unsigned int. Does this mean a comparison occurs before promoting a signed integer to an unsigned integer?










share|improve this question




















  • 6





    As you can see -10 is not converted to unsigned int. It is.

    – tkausl
    1 hour ago











  • Google about binary numbers and the way they are represented, in particular signedness. Then all shall become clear.

    – DeiDei
    1 hour ago














7












7








7


3






After getting advised to read "C++ Primer 5 ed by Stanley B. Lipman" I don't understand this:



Page 66. "Expressions Involving Unsigned Types"



unsigned u = 10;
int i = -42;
std::cout << i + i << std::endl; // prints -84
std::cout << u + i << std::endl; // if 32-bit ints, prints 4294967264


He said:




In the second expression, the int value -42 is converted to unsigned before the addition is done. Converting a negative number to unsigned behaves exactly as if we had attempted to assign that negative value to an unsigned object. The value “wraps around” as described above.




But if I do something like this:



unsigned u = 42;
int i = -10;
std::cout << u + i << std::endl; // Why the result is 32?


As you can see -10 is not converted to unsigned int. Does this mean a comparison occurs before promoting a signed integer to an unsigned integer?










share|improve this question
















After getting advised to read "C++ Primer 5 ed by Stanley B. Lipman" I don't understand this:



Page 66. "Expressions Involving Unsigned Types"



unsigned u = 10;
int i = -42;
std::cout << i + i << std::endl; // prints -84
std::cout << u + i << std::endl; // if 32-bit ints, prints 4294967264


He said:




In the second expression, the int value -42 is converted to unsigned before the addition is done. Converting a negative number to unsigned behaves exactly as if we had attempted to assign that negative value to an unsigned object. The value “wraps around” as described above.




But if I do something like this:



unsigned u = 42;
int i = -10;
std::cout << u + i << std::endl; // Why the result is 32?


As you can see -10 is not converted to unsigned int. Does this mean a comparison occurs before promoting a signed integer to an unsigned integer?







c++ unsigned-integer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 50 mins ago









NathanOliver

88.7k15120185




88.7k15120185










asked 1 hour ago









Alex24Alex24

1076




1076








  • 6





    As you can see -10 is not converted to unsigned int. It is.

    – tkausl
    1 hour ago











  • Google about binary numbers and the way they are represented, in particular signedness. Then all shall become clear.

    – DeiDei
    1 hour ago














  • 6





    As you can see -10 is not converted to unsigned int. It is.

    – tkausl
    1 hour ago











  • Google about binary numbers and the way they are represented, in particular signedness. Then all shall become clear.

    – DeiDei
    1 hour ago








6




6





As you can see -10 is not converted to unsigned int. It is.

– tkausl
1 hour ago





As you can see -10 is not converted to unsigned int. It is.

– tkausl
1 hour ago













Google about binary numbers and the way they are represented, in particular signedness. Then all shall become clear.

– DeiDei
1 hour ago





Google about binary numbers and the way they are represented, in particular signedness. Then all shall become clear.

– DeiDei
1 hour ago












5 Answers
5






active

oldest

votes


















6














-10 is being converted to a unsigned integer with a very large value, the reason you get a small number is that the addition wraps you back around. With 32 bit unsigned integers -10 is the same as 4294967286. When you add 42 to that you get 4294967328, but the max value is 4294967296, so we have to take 4294967328 modulo 4294967296 and we get 32.






share|improve this answer

































    5














    Well, I guess this is an exception to "two wrongs don't make a right" :)



    What is happening is that there are actually two wrap arounds (unsigned overflows) under the hood and the final result is ends up being mathematically correct.




    • First, i is converted to unsigned and as per wrap around behavior the value is std::numeric_limits<unsigned>::max() - 9.


    • When this value is summed with u the mathematical result would be std::numeric_limits<unsigned>::max() - 9 + 42 == std::numeric_limits<unsigned>::max() + 33 which is an overflow and we get another wrap around. So the final result is 32.





    As a general rule in an arithmetic expression if you only have unsigned overflows (no matter how many) and if the final mathematical result is representable in the expression data type, then the value of the expression will be the mathematically correct one. This is a consequence of the fact that unsigned integers in C++ obey the laws of arithmetic modulo 2n (see bellow).





    Important notice. According to C++ unsigned arithmetic does not overflow:




    §6.9.1 Fundamental types [basic.fundamental]




    1. Unsigned integers shall obey the laws of arithmetic modulo 2n where n
      is the number of bits in the value representation of that particular
      size of integer 49


    49) This implies that unsigned arithmetic does not overflow because a
    result that cannot be represented by the resulting unsigned integer
    type is reduced modulo the number that is one greater than the largest
    value that can be represented by the resulting unsigned integer type.




    I will however leave "overflow" in my answer to signify values that cannot be represented in regular arithmetic.



    Also what we colloquially call "wrap around" is in fact just the arithmetic modulo nature of the unsigned integers. I will however use "wrap around" also because it is easier to understand.






    share|improve this answer


























    • Unsigned arithmetic does not overflow.

      – Baum mit Augen
      56 mins ago











    • afaik it does and it is well defined

      – bolov
      55 mins ago






    • 1





      @BaummitAugen what? of course it overflows. Add two large unsigned ints, you can't represent a number that doesn't fit in the number format

      – Garr Godfrey
      54 mins ago











    • No. It can represent any integer by picking the representative of its equivalence class that lies in [0, 2^NumBit - 1]. Overflow occurs when some result cannot be represented. That cannot happen in unsigned arithmetic.

      – Baum mit Augen
      54 mins ago











    • @GarrGodfrey Yes it can represent the result. You are misunderstanding the arithmetic it implements.

      – Baum mit Augen
      54 mins ago





















    4














    i is in fact promoted to unsigned int.



    Unsigned integers in C and C++ implement arithmetic in ℤ / 2n, where n is the number of bits in the unsigned integer type. Thus we get



    [42] + [-10] ≡ [42] + [2n - 10] ≡ [2n + 32] ≡ [32],



    with [x] denoting the equivalence class of x in ℤ / 2n.






    share|improve this answer

































      3















      "In the second expression, the int value -42 is converted to unsigned before the addition is done"




      yes this is true




      unsigned u = 42;
      int i = -10;
      std::cout << u + i << std::endl; // Why the result is 32?



      Supposing we are in 32 bits (that change nothing in 64b, this is just to explain) this is computed as 42u + ((unsigned) -10) so 42u + 4294967286u and the result is 4294967328u truncated in 32 bits so 32. All was done in unsigned






      share|improve this answer































        1














        This is part of what is wonderful about 2's complement representation. The processor doesn't know or care if a number is signed or unsigned, the operations are the same. In both cases, the calculation is correct. It's only how the binary number is interpreted after the fact, when printing, that is actually matters (there may be other cases, as with comparison operators)



        -10 in 32BIT binary is FFFFFFF6
        42 IN 32bit BINARY is 0000002A


        Adding them together, it doesn't matter to the processor if they are signed or unsigned, the result is: 100000020. In 32bit, the 1 at the start will be placed in the overflow register, and in c++ is just disappears. You get 0x20 as the result, which is 32.



        In the first case, it is basically the same:



        -42 in 32BIT binary is FFFFFFD6
        10 IN 32bit binary is 0000000A


        Add those together and get FFFFFFE0



        FFFFFFE0 as a signed int is -32 (decimal). The calculation is correct! But, because it is being PRINTED as an unsigned, it shows up as 4294967264. It's about interpreting the result.






        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%2f54190113%2fif-a-negative-integer-summed-with-a-greater-unsiged-integer-is-promoted-to-unsig%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          5 Answers
          5






          active

          oldest

          votes








          5 Answers
          5






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          6














          -10 is being converted to a unsigned integer with a very large value, the reason you get a small number is that the addition wraps you back around. With 32 bit unsigned integers -10 is the same as 4294967286. When you add 42 to that you get 4294967328, but the max value is 4294967296, so we have to take 4294967328 modulo 4294967296 and we get 32.






          share|improve this answer






























            6














            -10 is being converted to a unsigned integer with a very large value, the reason you get a small number is that the addition wraps you back around. With 32 bit unsigned integers -10 is the same as 4294967286. When you add 42 to that you get 4294967328, but the max value is 4294967296, so we have to take 4294967328 modulo 4294967296 and we get 32.






            share|improve this answer




























              6












              6








              6







              -10 is being converted to a unsigned integer with a very large value, the reason you get a small number is that the addition wraps you back around. With 32 bit unsigned integers -10 is the same as 4294967286. When you add 42 to that you get 4294967328, but the max value is 4294967296, so we have to take 4294967328 modulo 4294967296 and we get 32.






              share|improve this answer















              -10 is being converted to a unsigned integer with a very large value, the reason you get a small number is that the addition wraps you back around. With 32 bit unsigned integers -10 is the same as 4294967286. When you add 42 to that you get 4294967328, but the max value is 4294967296, so we have to take 4294967328 modulo 4294967296 and we get 32.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 51 mins ago

























              answered 1 hour ago









              NathanOliverNathanOliver

              88.7k15120185




              88.7k15120185

























                  5














                  Well, I guess this is an exception to "two wrongs don't make a right" :)



                  What is happening is that there are actually two wrap arounds (unsigned overflows) under the hood and the final result is ends up being mathematically correct.




                  • First, i is converted to unsigned and as per wrap around behavior the value is std::numeric_limits<unsigned>::max() - 9.


                  • When this value is summed with u the mathematical result would be std::numeric_limits<unsigned>::max() - 9 + 42 == std::numeric_limits<unsigned>::max() + 33 which is an overflow and we get another wrap around. So the final result is 32.





                  As a general rule in an arithmetic expression if you only have unsigned overflows (no matter how many) and if the final mathematical result is representable in the expression data type, then the value of the expression will be the mathematically correct one. This is a consequence of the fact that unsigned integers in C++ obey the laws of arithmetic modulo 2n (see bellow).





                  Important notice. According to C++ unsigned arithmetic does not overflow:




                  §6.9.1 Fundamental types [basic.fundamental]




                  1. Unsigned integers shall obey the laws of arithmetic modulo 2n where n
                    is the number of bits in the value representation of that particular
                    size of integer 49


                  49) This implies that unsigned arithmetic does not overflow because a
                  result that cannot be represented by the resulting unsigned integer
                  type is reduced modulo the number that is one greater than the largest
                  value that can be represented by the resulting unsigned integer type.




                  I will however leave "overflow" in my answer to signify values that cannot be represented in regular arithmetic.



                  Also what we colloquially call "wrap around" is in fact just the arithmetic modulo nature of the unsigned integers. I will however use "wrap around" also because it is easier to understand.






                  share|improve this answer


























                  • Unsigned arithmetic does not overflow.

                    – Baum mit Augen
                    56 mins ago











                  • afaik it does and it is well defined

                    – bolov
                    55 mins ago






                  • 1





                    @BaummitAugen what? of course it overflows. Add two large unsigned ints, you can't represent a number that doesn't fit in the number format

                    – Garr Godfrey
                    54 mins ago











                  • No. It can represent any integer by picking the representative of its equivalence class that lies in [0, 2^NumBit - 1]. Overflow occurs when some result cannot be represented. That cannot happen in unsigned arithmetic.

                    – Baum mit Augen
                    54 mins ago











                  • @GarrGodfrey Yes it can represent the result. You are misunderstanding the arithmetic it implements.

                    – Baum mit Augen
                    54 mins ago


















                  5














                  Well, I guess this is an exception to "two wrongs don't make a right" :)



                  What is happening is that there are actually two wrap arounds (unsigned overflows) under the hood and the final result is ends up being mathematically correct.




                  • First, i is converted to unsigned and as per wrap around behavior the value is std::numeric_limits<unsigned>::max() - 9.


                  • When this value is summed with u the mathematical result would be std::numeric_limits<unsigned>::max() - 9 + 42 == std::numeric_limits<unsigned>::max() + 33 which is an overflow and we get another wrap around. So the final result is 32.





                  As a general rule in an arithmetic expression if you only have unsigned overflows (no matter how many) and if the final mathematical result is representable in the expression data type, then the value of the expression will be the mathematically correct one. This is a consequence of the fact that unsigned integers in C++ obey the laws of arithmetic modulo 2n (see bellow).





                  Important notice. According to C++ unsigned arithmetic does not overflow:




                  §6.9.1 Fundamental types [basic.fundamental]




                  1. Unsigned integers shall obey the laws of arithmetic modulo 2n where n
                    is the number of bits in the value representation of that particular
                    size of integer 49


                  49) This implies that unsigned arithmetic does not overflow because a
                  result that cannot be represented by the resulting unsigned integer
                  type is reduced modulo the number that is one greater than the largest
                  value that can be represented by the resulting unsigned integer type.




                  I will however leave "overflow" in my answer to signify values that cannot be represented in regular arithmetic.



                  Also what we colloquially call "wrap around" is in fact just the arithmetic modulo nature of the unsigned integers. I will however use "wrap around" also because it is easier to understand.






                  share|improve this answer


























                  • Unsigned arithmetic does not overflow.

                    – Baum mit Augen
                    56 mins ago











                  • afaik it does and it is well defined

                    – bolov
                    55 mins ago






                  • 1





                    @BaummitAugen what? of course it overflows. Add two large unsigned ints, you can't represent a number that doesn't fit in the number format

                    – Garr Godfrey
                    54 mins ago











                  • No. It can represent any integer by picking the representative of its equivalence class that lies in [0, 2^NumBit - 1]. Overflow occurs when some result cannot be represented. That cannot happen in unsigned arithmetic.

                    – Baum mit Augen
                    54 mins ago











                  • @GarrGodfrey Yes it can represent the result. You are misunderstanding the arithmetic it implements.

                    – Baum mit Augen
                    54 mins ago
















                  5












                  5








                  5







                  Well, I guess this is an exception to "two wrongs don't make a right" :)



                  What is happening is that there are actually two wrap arounds (unsigned overflows) under the hood and the final result is ends up being mathematically correct.




                  • First, i is converted to unsigned and as per wrap around behavior the value is std::numeric_limits<unsigned>::max() - 9.


                  • When this value is summed with u the mathematical result would be std::numeric_limits<unsigned>::max() - 9 + 42 == std::numeric_limits<unsigned>::max() + 33 which is an overflow and we get another wrap around. So the final result is 32.





                  As a general rule in an arithmetic expression if you only have unsigned overflows (no matter how many) and if the final mathematical result is representable in the expression data type, then the value of the expression will be the mathematically correct one. This is a consequence of the fact that unsigned integers in C++ obey the laws of arithmetic modulo 2n (see bellow).





                  Important notice. According to C++ unsigned arithmetic does not overflow:




                  §6.9.1 Fundamental types [basic.fundamental]




                  1. Unsigned integers shall obey the laws of arithmetic modulo 2n where n
                    is the number of bits in the value representation of that particular
                    size of integer 49


                  49) This implies that unsigned arithmetic does not overflow because a
                  result that cannot be represented by the resulting unsigned integer
                  type is reduced modulo the number that is one greater than the largest
                  value that can be represented by the resulting unsigned integer type.




                  I will however leave "overflow" in my answer to signify values that cannot be represented in regular arithmetic.



                  Also what we colloquially call "wrap around" is in fact just the arithmetic modulo nature of the unsigned integers. I will however use "wrap around" also because it is easier to understand.






                  share|improve this answer















                  Well, I guess this is an exception to "two wrongs don't make a right" :)



                  What is happening is that there are actually two wrap arounds (unsigned overflows) under the hood and the final result is ends up being mathematically correct.




                  • First, i is converted to unsigned and as per wrap around behavior the value is std::numeric_limits<unsigned>::max() - 9.


                  • When this value is summed with u the mathematical result would be std::numeric_limits<unsigned>::max() - 9 + 42 == std::numeric_limits<unsigned>::max() + 33 which is an overflow and we get another wrap around. So the final result is 32.





                  As a general rule in an arithmetic expression if you only have unsigned overflows (no matter how many) and if the final mathematical result is representable in the expression data type, then the value of the expression will be the mathematically correct one. This is a consequence of the fact that unsigned integers in C++ obey the laws of arithmetic modulo 2n (see bellow).





                  Important notice. According to C++ unsigned arithmetic does not overflow:




                  §6.9.1 Fundamental types [basic.fundamental]




                  1. Unsigned integers shall obey the laws of arithmetic modulo 2n where n
                    is the number of bits in the value representation of that particular
                    size of integer 49


                  49) This implies that unsigned arithmetic does not overflow because a
                  result that cannot be represented by the resulting unsigned integer
                  type is reduced modulo the number that is one greater than the largest
                  value that can be represented by the resulting unsigned integer type.




                  I will however leave "overflow" in my answer to signify values that cannot be represented in regular arithmetic.



                  Also what we colloquially call "wrap around" is in fact just the arithmetic modulo nature of the unsigned integers. I will however use "wrap around" also because it is easier to understand.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 12 mins ago









                  ruakh

                  124k13199252




                  124k13199252










                  answered 1 hour ago









                  bolovbolov

                  30.9k669128




                  30.9k669128













                  • Unsigned arithmetic does not overflow.

                    – Baum mit Augen
                    56 mins ago











                  • afaik it does and it is well defined

                    – bolov
                    55 mins ago






                  • 1





                    @BaummitAugen what? of course it overflows. Add two large unsigned ints, you can't represent a number that doesn't fit in the number format

                    – Garr Godfrey
                    54 mins ago











                  • No. It can represent any integer by picking the representative of its equivalence class that lies in [0, 2^NumBit - 1]. Overflow occurs when some result cannot be represented. That cannot happen in unsigned arithmetic.

                    – Baum mit Augen
                    54 mins ago











                  • @GarrGodfrey Yes it can represent the result. You are misunderstanding the arithmetic it implements.

                    – Baum mit Augen
                    54 mins ago





















                  • Unsigned arithmetic does not overflow.

                    – Baum mit Augen
                    56 mins ago











                  • afaik it does and it is well defined

                    – bolov
                    55 mins ago






                  • 1





                    @BaummitAugen what? of course it overflows. Add two large unsigned ints, you can't represent a number that doesn't fit in the number format

                    – Garr Godfrey
                    54 mins ago











                  • No. It can represent any integer by picking the representative of its equivalence class that lies in [0, 2^NumBit - 1]. Overflow occurs when some result cannot be represented. That cannot happen in unsigned arithmetic.

                    – Baum mit Augen
                    54 mins ago











                  • @GarrGodfrey Yes it can represent the result. You are misunderstanding the arithmetic it implements.

                    – Baum mit Augen
                    54 mins ago



















                  Unsigned arithmetic does not overflow.

                  – Baum mit Augen
                  56 mins ago





                  Unsigned arithmetic does not overflow.

                  – Baum mit Augen
                  56 mins ago













                  afaik it does and it is well defined

                  – bolov
                  55 mins ago





                  afaik it does and it is well defined

                  – bolov
                  55 mins ago




                  1




                  1





                  @BaummitAugen what? of course it overflows. Add two large unsigned ints, you can't represent a number that doesn't fit in the number format

                  – Garr Godfrey
                  54 mins ago





                  @BaummitAugen what? of course it overflows. Add two large unsigned ints, you can't represent a number that doesn't fit in the number format

                  – Garr Godfrey
                  54 mins ago













                  No. It can represent any integer by picking the representative of its equivalence class that lies in [0, 2^NumBit - 1]. Overflow occurs when some result cannot be represented. That cannot happen in unsigned arithmetic.

                  – Baum mit Augen
                  54 mins ago





                  No. It can represent any integer by picking the representative of its equivalence class that lies in [0, 2^NumBit - 1]. Overflow occurs when some result cannot be represented. That cannot happen in unsigned arithmetic.

                  – Baum mit Augen
                  54 mins ago













                  @GarrGodfrey Yes it can represent the result. You are misunderstanding the arithmetic it implements.

                  – Baum mit Augen
                  54 mins ago







                  @GarrGodfrey Yes it can represent the result. You are misunderstanding the arithmetic it implements.

                  – Baum mit Augen
                  54 mins ago













                  4














                  i is in fact promoted to unsigned int.



                  Unsigned integers in C and C++ implement arithmetic in ℤ / 2n, where n is the number of bits in the unsigned integer type. Thus we get



                  [42] + [-10] ≡ [42] + [2n - 10] ≡ [2n + 32] ≡ [32],



                  with [x] denoting the equivalence class of x in ℤ / 2n.






                  share|improve this answer






























                    4














                    i is in fact promoted to unsigned int.



                    Unsigned integers in C and C++ implement arithmetic in ℤ / 2n, where n is the number of bits in the unsigned integer type. Thus we get



                    [42] + [-10] ≡ [42] + [2n - 10] ≡ [2n + 32] ≡ [32],



                    with [x] denoting the equivalence class of x in ℤ / 2n.






                    share|improve this answer




























                      4












                      4








                      4







                      i is in fact promoted to unsigned int.



                      Unsigned integers in C and C++ implement arithmetic in ℤ / 2n, where n is the number of bits in the unsigned integer type. Thus we get



                      [42] + [-10] ≡ [42] + [2n - 10] ≡ [2n + 32] ≡ [32],



                      with [x] denoting the equivalence class of x in ℤ / 2n.






                      share|improve this answer















                      i is in fact promoted to unsigned int.



                      Unsigned integers in C and C++ implement arithmetic in ℤ / 2n, where n is the number of bits in the unsigned integer type. Thus we get



                      [42] + [-10] ≡ [42] + [2n - 10] ≡ [2n + 32] ≡ [32],



                      with [x] denoting the equivalence class of x in ℤ / 2n.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 59 mins ago

























                      answered 1 hour ago









                      Baum mit AugenBaum mit Augen

                      40.4k12115147




                      40.4k12115147























                          3















                          "In the second expression, the int value -42 is converted to unsigned before the addition is done"




                          yes this is true




                          unsigned u = 42;
                          int i = -10;
                          std::cout << u + i << std::endl; // Why the result is 32?



                          Supposing we are in 32 bits (that change nothing in 64b, this is just to explain) this is computed as 42u + ((unsigned) -10) so 42u + 4294967286u and the result is 4294967328u truncated in 32 bits so 32. All was done in unsigned






                          share|improve this answer




























                            3















                            "In the second expression, the int value -42 is converted to unsigned before the addition is done"




                            yes this is true




                            unsigned u = 42;
                            int i = -10;
                            std::cout << u + i << std::endl; // Why the result is 32?



                            Supposing we are in 32 bits (that change nothing in 64b, this is just to explain) this is computed as 42u + ((unsigned) -10) so 42u + 4294967286u and the result is 4294967328u truncated in 32 bits so 32. All was done in unsigned






                            share|improve this answer


























                              3












                              3








                              3








                              "In the second expression, the int value -42 is converted to unsigned before the addition is done"




                              yes this is true




                              unsigned u = 42;
                              int i = -10;
                              std::cout << u + i << std::endl; // Why the result is 32?



                              Supposing we are in 32 bits (that change nothing in 64b, this is just to explain) this is computed as 42u + ((unsigned) -10) so 42u + 4294967286u and the result is 4294967328u truncated in 32 bits so 32. All was done in unsigned






                              share|improve this answer














                              "In the second expression, the int value -42 is converted to unsigned before the addition is done"




                              yes this is true




                              unsigned u = 42;
                              int i = -10;
                              std::cout << u + i << std::endl; // Why the result is 32?



                              Supposing we are in 32 bits (that change nothing in 64b, this is just to explain) this is computed as 42u + ((unsigned) -10) so 42u + 4294967286u and the result is 4294967328u truncated in 32 bits so 32. All was done in unsigned







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 1 hour ago









                              brunobruno

                              3,3141716




                              3,3141716























                                  1














                                  This is part of what is wonderful about 2's complement representation. The processor doesn't know or care if a number is signed or unsigned, the operations are the same. In both cases, the calculation is correct. It's only how the binary number is interpreted after the fact, when printing, that is actually matters (there may be other cases, as with comparison operators)



                                  -10 in 32BIT binary is FFFFFFF6
                                  42 IN 32bit BINARY is 0000002A


                                  Adding them together, it doesn't matter to the processor if they are signed or unsigned, the result is: 100000020. In 32bit, the 1 at the start will be placed in the overflow register, and in c++ is just disappears. You get 0x20 as the result, which is 32.



                                  In the first case, it is basically the same:



                                  -42 in 32BIT binary is FFFFFFD6
                                  10 IN 32bit binary is 0000000A


                                  Add those together and get FFFFFFE0



                                  FFFFFFE0 as a signed int is -32 (decimal). The calculation is correct! But, because it is being PRINTED as an unsigned, it shows up as 4294967264. It's about interpreting the result.






                                  share|improve this answer




























                                    1














                                    This is part of what is wonderful about 2's complement representation. The processor doesn't know or care if a number is signed or unsigned, the operations are the same. In both cases, the calculation is correct. It's only how the binary number is interpreted after the fact, when printing, that is actually matters (there may be other cases, as with comparison operators)



                                    -10 in 32BIT binary is FFFFFFF6
                                    42 IN 32bit BINARY is 0000002A


                                    Adding them together, it doesn't matter to the processor if they are signed or unsigned, the result is: 100000020. In 32bit, the 1 at the start will be placed in the overflow register, and in c++ is just disappears. You get 0x20 as the result, which is 32.



                                    In the first case, it is basically the same:



                                    -42 in 32BIT binary is FFFFFFD6
                                    10 IN 32bit binary is 0000000A


                                    Add those together and get FFFFFFE0



                                    FFFFFFE0 as a signed int is -32 (decimal). The calculation is correct! But, because it is being PRINTED as an unsigned, it shows up as 4294967264. It's about interpreting the result.






                                    share|improve this answer


























                                      1












                                      1








                                      1







                                      This is part of what is wonderful about 2's complement representation. The processor doesn't know or care if a number is signed or unsigned, the operations are the same. In both cases, the calculation is correct. It's only how the binary number is interpreted after the fact, when printing, that is actually matters (there may be other cases, as with comparison operators)



                                      -10 in 32BIT binary is FFFFFFF6
                                      42 IN 32bit BINARY is 0000002A


                                      Adding them together, it doesn't matter to the processor if they are signed or unsigned, the result is: 100000020. In 32bit, the 1 at the start will be placed in the overflow register, and in c++ is just disappears. You get 0x20 as the result, which is 32.



                                      In the first case, it is basically the same:



                                      -42 in 32BIT binary is FFFFFFD6
                                      10 IN 32bit binary is 0000000A


                                      Add those together and get FFFFFFE0



                                      FFFFFFE0 as a signed int is -32 (decimal). The calculation is correct! But, because it is being PRINTED as an unsigned, it shows up as 4294967264. It's about interpreting the result.






                                      share|improve this answer













                                      This is part of what is wonderful about 2's complement representation. The processor doesn't know or care if a number is signed or unsigned, the operations are the same. In both cases, the calculation is correct. It's only how the binary number is interpreted after the fact, when printing, that is actually matters (there may be other cases, as with comparison operators)



                                      -10 in 32BIT binary is FFFFFFF6
                                      42 IN 32bit BINARY is 0000002A


                                      Adding them together, it doesn't matter to the processor if they are signed or unsigned, the result is: 100000020. In 32bit, the 1 at the start will be placed in the overflow register, and in c++ is just disappears. You get 0x20 as the result, which is 32.



                                      In the first case, it is basically the same:



                                      -42 in 32BIT binary is FFFFFFD6
                                      10 IN 32bit binary is 0000000A


                                      Add those together and get FFFFFFE0



                                      FFFFFFE0 as a signed int is -32 (decimal). The calculation is correct! But, because it is being PRINTED as an unsigned, it shows up as 4294967264. It's about interpreting the result.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered 56 mins ago









                                      Garr GodfreyGarr Godfrey

                                      4,02711518




                                      4,02711518






























                                          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%2f54190113%2fif-a-negative-integer-summed-with-a-greater-unsiged-integer-is-promoted-to-unsig%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

                                          Knooppunt Holsloot

                                          Altaar (religie)

                                          Gregoriusmis