signed number question

Feb 21, 2013 at 6:35am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <cstdlib>
#include <math.h>
#include <climits>


using namespace std;

int main()
{
    // SHRT_MAX = 32767

    short s1 ;
    short s2 ;

    s1 = s2 = SHRT_MAX;

    s1 = s1 + 1; // s1 + 1

    cout << "s1 : " << s1 << endl;
    cout << "s2 : " << s2 + 1; // s2 + 1

    return 0;

}


s1 : -32768
s2 : 32768


i dont understand the "s2" value's going on
Last edited on Feb 21, 2013 at 6:37am
Feb 21, 2013 at 9:00am
Feb 21, 2013 at 11:13am
There is no operator+ for shorts, but there is one for ints, so when you write s1 + 1, you're actually asking the compiler to first promote your s1 to an int (which preserves the value: 32767 short becomes 32767 int), and then you're asking to add 1 (which is an int) to that. (technically it's a bit more complicated, search for "usual arithmetic conversions", or read
http://en.cppreference.com/w/cpp/language/operator_arithmetic )

The result, on a platform with greater than 16-bit ints, is 32768, and its type is int

Now, in the expression "cout << s2 + 1", you're using operator<<(ostream&, int) to print that int, and that's why you see the value 32768

In the expression s1 = s1 + 1, you're stuffing the int 32768 into a short. Because the short is signed, this is undefined behavior, but in your case (as in most cases) this simply produced the value according to 2's complement rules linked by kbw.
Last edited on Feb 21, 2013 at 11:32am
Feb 21, 2013 at 12:00pm
@Cubbi
There is no operator+ for shorts,


I can not agree with this statement because according to the C++ Standard

"For addition, either both operands shall have arithmetic or unscoped enumeration type, ..."


As short is an arithmetic type so there is additive operator + even though "
The usual arithmetic conversions are performed for operands of arithmetic or enumeration type."
(C++ Standard)
Feb 21, 2013 at 12:20pm
the point is that 'signed' is a matter of interpretation. The most significant bit is used as the indicator for a signed value being negative.

The addition or other mathematical expressions boils down to bit manipulation. if the result is that the most significant bit is set and the value is considered signed you will see a negative value.

Try this
1
2
unsigned short s = 0;
s = s - 1;
Last edited on Feb 21, 2013 at 12:21pm
Feb 21, 2013 at 2:21pm
There is no operator+ for shorts,
I can not agree with this statement because according to the C++ Standard

I was referring to the fact that operator+(short, short) (or operator+(short,int), for this case) does not participate in overload resolution, unlike operator+(int, int), see §13.6[over.built]/12. It is a simple way to introduce usual arithmetic conversions.
Last edited on Feb 21, 2013 at 2:22pm
Feb 22, 2013 at 5:11am
thank you guys !!!!
was the type of s1 became "Short" and then the type of s2 was became "Integer"(or the s2 value was not be changed to short , just staying in integer) ?
that means the s2 would be printed by integer in cout?
Last edited on Feb 22, 2013 at 5:39am
Feb 22, 2013 at 7:12am
Signed integral values always wrap. It's the way 2s compliment work. It has nothing to do with the language and user defined operations.
Feb 22, 2013 at 9:00am
What I think what happens in case of "s2" is that 1 is considered as an integer and since it the result is not determined all operands are implicitly converted to the (bitwise) greatest operand (the integer)
Feb 22, 2013 at 9:32am
> Signed integral values always wrap.

In the C programming language, signed integer overflow causes undefined behavior, while unsigned integer overflow causes the number to be reduced modulo a power of two, meaning that unsigned integers "wrap around" on overflow.
http://en.wikipedia.org/wiki/Integer_overflow


> What I think what happens in case of "s2" is that 1 is considered as an integer ...
> all operands are implicitly converted to the (bitwise) greatest operand (the integer)

Yes, but:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

const char* type(short) { return "short" ; }
const char* type(int) { return "int" ; }

int main()
{
   short a = 0, b = 0 ;
   std::cout << type(a) << '\n' // short
             << type( +a ) << '\n' // int
             << type( a + b ) << '\n' ; // int
}
Feb 22, 2013 at 11:19am
signed integer overflow causes undefined behavior
It's undefined because the architectures aren't predetermined. On a 2's compliment system with a known byte size, the behaviour is deterministic.
Feb 22, 2013 at 11:23am
It may have been the reasoning why it was left undefined historically, but today optimizing compilers rely on that the programmers never let it happen.
Topic archived. No new replies allowed.