473,388 Members | 1,382 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

A trick question

Gio
Expand|Select|Wrap|Line Numbers
  1.  
  2. short i, j;
  3.  
  4. i = -32768;
  5. j = -i;
  6.  
  7. printf("%d", j);
  8.  
  9.  
As some of you may have guessed by my previous post (about books), I'm
trying to learn C. Well, a friend of mine (who is a programmer) asked me
(who is not a programmer) what the output of this would be, and why. I
had no clue, so I ran it, and it printed -32768. I gave him my best
guess (which was wrong):
1) a short maxes out at 32768, so it has no more room to hold the
sign info. That's it for i, anyway. When you define j as -i, it's
saying "here's some sign info, then look at i", not actually doing
the math as -1 * i.
My second guess was:
2) There are little gremlins in my compiler changing signs of my
numbers around. Darn gremlins!
Okay, so that one was wrong too. :(

I have to say, I'm a little bothered by this. Why does it print -32768?

- Gio

--
AND NOW FOR A WORD (an IF blog):

http://giomancer.wordpress.com/
Jun 27 '08 #1
22 1707
Gio wrote:
Expand|Select|Wrap|Line Numbers
  1. short i, j;
  2. i = -32768;
  3. j = -i;
  4. printf("%d", j);
  5.  

As some of you may have guessed by my previous post (about books), I'm
trying to learn C. Well, a friend of mine (who is a programmer) asked me
(who is not a programmer) what the output of this would be, and why. I
had no clue, so I ran it, and it printed -32768. I gave him my best
guess (which was wrong):
>1) a short maxes out at 32768, so it has no more room to hold the sign
info. That's it for i, anyway. When you define j as -i, it's saying
"here's some sign info, then look at i", not actually doing the math
as -1 * i.

My second guess was:
>2) There are little gremlins in my compiler changing signs of my
numbers around. Darn gremlins!

Okay, so that one was wrong too. :(

I have to say, I'm a little bothered by this. Why does it print -32768?

Try the following:

#include <stdio.h>

int main(void)
{
short i, j;

i= -32767;

j= -i;

printf("%d\n", j);

i= i- 1;

j= -i;

printf("%d\n", j);

return 0;
}
Give us what this program outputs to your system, and try to explain us
what is happening on each statement.
Jun 27 '08 #2
The code fixed:
Ioannis Vranos wrote:
Gio wrote:
>
Expand|Select|Wrap|Line Numbers
  1. short i, j;
  2. i = -32768;
  3. j = -i;
  4. printf("%d", j);

As some of you may have guessed by my previous post (about books), I'm
trying to learn C. Well, a friend of mine (who is a programmer) asked me
(who is not a programmer) what the output of this would be, and why. I
had no clue, so I ran it, and it printed -32768. I gave him my best
guess (which was wrong):
>>1) a short maxes out at 32768, so it has no more room to hold the sign
info. That's it for i, anyway. When you define j as -i, it's saying
"here's some sign info, then look at i", not actually doing the math
as -1 * i.
My second guess was:
>>2) There are little gremlins in my compiler changing signs of my
numbers around. Darn gremlins!
Okay, so that one was wrong too. :(

I have to say, I'm a little bothered by this. Why does it print -32768?

Try the following:
#include <stdio.h>

int main(void)
{
short i, j;

i= -32767;

j= -i;

printf("i= %hd\n", i);

printf("j= %hd\n\n", j);
i= i- 1;

j= -i;

printf("i= %hd\n", i);

printf("j= %hd\n", j);
return 0;
}

Give us what this program outputs to your system, and try to explain us
what is happening on each statement.
Jun 27 '08 #3
Gio said:
Expand|Select|Wrap|Line Numbers
  1. short i, j;
  2. i = -32768;
  3. j = -i;
  4. printf("%d", j);
  5.  

As some of you may have guessed by my previous post (about books), I'm
trying to learn C. Well, a friend of mine (who is a programmer) asked me
(who is not a programmer) what the output of this would be, and why.
Let's start off by assuming a simpler case, where i is -1, so j takes the
value 1. Since printf is a variadic function, "the default argument
promotions are performed on trailing arguments" (as the Standard says), so
the short int value of 1 is promoted to an int, which matches %d just
fine. So the problem (and yes, there may be one) is not with the %d.

Okay, so i = -32768, and that's a problem right there, because it's outside
the minimum range for short int, which is -32767 to +32767.
Implementations are free to provide wider ranges, but are not forced to. I
*guess* that your implementation actually supports -32768 to +32767. If
I'm right, then what's happening is that the program is trying to assign
-(-32768), which is +32768, into an object that can't support a value that
high. The result is undefined, and the Standard doesn't say anything at
all about what will happen. So whatever gets printed, count yourself lucky
that you probably didn't catch bubonic plague from this code.

But why -32768?

Okay, bearing in mind that the result is undefined so there doesn't even
have to *be* a reason, let's try to see if we can find one anyway.

Let's reduce the problem to four bits (a *really* short int).

You're doing this:

reallyshort i, j;
i = -8; /* bit pattern 1000, two's complement */
j = -i;

C promotes -8 to an int, and then does a unary minus on it, giving 8.
Assuming 16-bit ints (and the same argument applies to larger ints), this
has a bit pattern of 0000000000001000. If we're going to load this value
into j (which has only four bits), something has to give, and it's the
high bits that go, so j gets the value 1000, which is -8!

Using four bits per reallyshort saved me some typing and counting, but
precisely the same argument applies to 16-bit shorts, the only difference
being that a lot more 0s and 1s are involved.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #4
Richard Heathfield wrote:
Gio said:
>
Expand|Select|Wrap|Line Numbers
  1. short i, j;
  2. i = -32768;
  3. j = -i;
  4. printf("%d", j);

As some of you may have guessed by my previous post (about books), I'm
trying to learn C. Well, a friend of mine (who is a programmer) asked me
(who is not a programmer) what the output of this would be, and why.

Let's start off by assuming a simpler case, where i is -1, so j takes the
value 1. Since printf is a variadic function, "the default argument
promotions are performed on trailing arguments" (as the Standard says), so
the short int value of 1 is promoted to an int, which matches %d just
fine. So the problem (and yes, there may be one) is not with the %d.

Okay, so i = -32768, and that's a problem right there, because it's outside
the minimum range for short int, which is -32767 to +32767.
Implementations are free to provide wider ranges, but are not forced to. I
*guess* that your implementation actually supports -32768 to +32767. If
I'm right, then what's happening is that the program is trying to assign
-(-32768), which is +32768, into an object that can't support a value that
high. The result is undefined, and the Standard doesn't say anything at
all about what will happen. So whatever gets printed, count yourself lucky
that you probably didn't catch bubonic plague from this code.

But why -32768?

Okay, bearing in mind that the result is undefined so there doesn't even
have to *be* a reason, let's try to see if we can find one anyway.

Let's reduce the problem to four bits (a *really* short int).

You're doing this:

reallyshort i, j;
i = -8; /* bit pattern 1000, two's complement */
j = -i;

C promotes -8 to an int, and then does a unary minus on it, giving 8.
Assuming 16-bit ints (and the same argument applies to larger ints), this
has a bit pattern of 0000000000001000. If we're going to load this value
into j (which has only four bits), something has to give, and it's the
high bits that go, so j gets the value 1000, which is -8!

Using four bits per reallyshort saved me some typing and counting, but
precisely the same argument applies to 16-bit shorts, the only difference
being that a lot more 0s and 1s are involved.

I think a better approach is to let him think what is happening at each
statement.

Jun 27 '08 #5
Gio wrote:
Expand|Select|Wrap|Line Numbers
  1. short i, j;
  2. i = -32768;
  3. j = -i;
  4. printf("%d", j);
  5.  

As some of you may have guessed by my previous post (about books), I'm
trying to learn C. Well, a friend of mine (who is a programmer) asked me
(who is not a programmer) what the output of this would be, and why. I
had no clue, so I ran it, and it printed -32768. I gave him my best
guess (which was wrong):
>1) a short maxes out at 32768, so it has no more room to hold the sign
info. That's it for i, anyway. When you define j as -i, it's saying
"here's some sign info, then look at i", not actually doing the math
as -1 * i.

My second guess was:
>2) There are little gremlins in my compiler changing signs of my
numbers around. Darn gremlins!

Okay, so that one was wrong too. :(

I have to say, I'm a little bothered by this. Why does it print -32768?

- Gio
Assuming twos complement and short is 16 bits, SHRT_MAX is 32767 or
0x7fff or 0111_1111_1111_1111. SHRT_MIN is -32768 or 0x8000 or
1000_0000_0000_0000.

In twos complement, to negate a value, we take its ones complement and
add one to it (Voila, twos).

Given 1000_0000_0000_0000 complementing it we have 0111_1111_1111_1111
and adding one we have 1000_0000_0000_0000 again.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jun 27 '08 #6
In article <wN******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>Okay, so i = -32768, and that's a problem right there, because it's outside
the minimum range for short int, which is -32767 to +32767.
Implementations are free to provide wider ranges, but are not forced to. I
*guess* that your implementation actually supports -32768 to +32767. If
I'm right, then what's happening is that the program is trying to assign
-(-32768), which is +32768, into an object that can't support a value that
high. The result is undefined, and the Standard doesn't say anything at
all about what will happen.
The situation gets even more complicated, due to the fact that
C parses -32768 as the unary minus operation applied to 32678 --
and by previous assumption, 32768 is greater than the maximum
signed short. Due to a chain of reasons, it is certain to all work out
for the case of assigning a literal -32768 to a signed int, but

long i = -2147483648;

is not certain to work even when signed long can store that value;
the code may have to be written as

long i = -2147483647-1;
--
"Product of a myriad various minds and contending tongues, compact of
obscure and minute association, a language has its own abundant and
often recondite laws, in the habitual and summary recognition of
which scholarship consists." -- Walter Pater
Jun 27 '08 #7
Gio wrote:
>
Expand|Select|Wrap|Line Numbers
  1. short i, j;
  2. i = -32768;
  3. j = -i;
  4. printf("%d", j);
  5.  

As some of you may have guessed by my previous post (about books),
I'm trying to learn C. Well, a friend of mine (who is a programmer)
asked me (who is not a programmer) what the output of this would
be, and why. I had no clue, so I ran it, and it printed -32768. I
gave him my best guess (which was wrong):
Because your system is (obviously) using 16 bits for integers.
INT_MAX will obviously be 32767 (see limits.h include file) so the
act of negating -32768 creates an overflow. Now you no longer have
any control over the program, since the result is either undefined
or implementation defined.

If you need portable code and values requiring 32 bits, use a
long. Then the size is guaranteed. Unsigned things also define
the action on 'overflow'.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #8
Gio
I had to modify the program to be used by my compiler (it's an old one;
I'm doing this on an Apple II)

Expand|Select|Wrap|Line Numbers
  1.  
  2. #include <stdio.h>
  3.  
  4. main()
  5. {
  6. short i, j;
  7.  
  8. i = -32767;
  9. j = -i;
  10.  
  11. printf("i = %x\n", i);
  12. printf("j = %x\n\n", j);
  13.  
  14. i = i - 1;
  15. j = -i;
  16.  
  17. printf("i = %x\n", i);
  18. printf("j = %x\n", j);
  19. }
  20.  
  21.  
So, I don't know if the output is what you intended, but here goes:

i = 8001
j = 7fff

i = 8000
j = 8000

- Gio

--
AND NOW FOR A WORD (an IF blog):

http://giomancer.wordpress.com/
Jun 27 '08 #9
Ioannis Vranos said:
Richard Heathfield wrote:
<snip>
>Using four bits per reallyshort saved me some typing and counting, but
precisely the same argument applies to 16-bit shorts, the only
difference being that a lot more 0s and 1s are involved.


I think a better approach is to let him think what is happening at each
statement.
Silly of me - I should have thought of that myself. Your solution to his
problem is not only brilliant but also widely applicable. It can be used
to answer almost every question asked here, and the only prerequisite on
the part of the questioner is a perfect knowledge of C.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #10
Gio wrote:
I had to modify the program to be used by my compiler (it's an old one;
I'm doing this on an Apple II)

What compiler and version are you using?

%hd did not work? If it didn't, use %d and use the following code instead:

#include <stdio.h>

int main(void)
{
short i;

i= 32767;

printf("i= %hd\n", i);

i= i+1;

printf("i= %hd\n", i);

i= i+1;

printf("i= %hd\n", i);
return 0;
}

Show us the output of the program and what you think each statement does.
Jun 27 '08 #11
Gio
Well, I'd like to thank you all for your answers. Not sure that I
understand them, but I shall study them. :)

- Gio

--
AND NOW FOR A WORD (an IF blog):

http://giomancer.wordpress.com/
Jun 27 '08 #12
Gio
What compiler and version are you using?

I am using Aztec-C. Its a version of C that's pretty close to but not
quite ANSI C.
%hd did not work? If it didn't, use %d and use the following code
instead:
Well.. it didn't give me any errors, but it just printed the same values
as %d would.

Output:

i = 32767
i = -32768
i = -32767

What it looks like to me is that it's turning over, like an odometer.

- Gio

--
AND NOW FOR A WORD (an IF blog):

http://giomancer.wordpress.com/
Jun 27 '08 #13
CBFalconer <cb********@yahoo.comwrites:
Gio wrote:
>
Expand|Select|Wrap|Line Numbers
  1. short i, j;
  2. i = -32768;
  3. j = -i;
  4. printf("%d", j);

As some of you may have guessed by my previous post (about books),
I'm trying to learn C. Well, a friend of mine (who is a programmer)
asked me (who is not a programmer) what the output of this would
be, and why. I had no clue, so I ran it, and it printed -32768. I
gave him my best guess (which was wrong):

Because your system is (obviously) using 16 bits for integers.
INT_MAX will obviously be 32767 (see limits.h include file) so the
act of negating -32768 creates an overflow. Now you no longer have
any control over the program, since the result is either undefined
or implementation defined.
Um, no.

By "integers", do you mean type int? Remember that there are several
integer types; "int" is just one of them. Yes, the implementation is
using 16 bits for integers, but (probably) only for integers of types
short and unsigned short.

The statement

i = -32768;

(where i is of type short) will work as long as SHRT_MIN is -32768 or
less (i.e., it can fail only if the range of short is exactly -32767
to +32767). The constant 32768 is of type short, int, or long,
whichever is the first in which it will fit. Negating it yields a
value of the same type, which cannot overflow, so you have an
expression of some signed integral type with the value -32768.

Assigning this to i causes it to be converted to short; this can fail
only if, as mentioned above, short's range is exactly -32767 to
+32767 (which is unusual for modern systems).

Now in this statement:

j = -i;

if short is 16 bits, the the unary "-" will overflow. The resulting
is behavior is undefined. A typical symptom of this undefined
behavior is that the value -32768 is assigned to j (given the typical
2's-complement implementation with no overflow checking).

Now if SHRT_MIN is -32767, then the situation is a bit different, but
that can only occur if the implementation uses 1's-complement or
sign-and-magnitude, or if uses 2's-commplement and reserves -32768 as
a trap represenation (I *think* that's permitted).
If you need portable code and values requiring 32 bits, use a
long. Then the size is guaranteed. Unsigned things also define
the action on 'overflow'.
Right. But you can assume that -32768 will fit in 16 bits *if* you
don't mind giving up portability to non-2's-complement implementations
(which might be a reasonable choice).

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #14
Gio wrote:
>What compiler and version are you using?

I am using Aztec-C. Its a version of C that's pretty close to but not
quite ANSI C.

What is the name and version of your operating system? Perhaps we can
help you get a more decent compiler.
>%hd did not work? If it didn't, use %d and use the following code
instead:

Well.. it didn't give me any errors, but it just printed the same values
as %d would.
%hd is the proper format specifier for shorts. %d is for ints, %ld is
for longs. You should use %hd for shorts.
>
Output:

i = 32767
i = -32768
i = -32767

What it looks like to me is that it's turning over, like an odometer.

Exactly, in your case it wraps around. You reach the maximum positive
value, and then it goes to the least negative value.

In C, it is guaranteed that all unsigned integer types wrap around after
they reach their maximum value, that is after their maximum value, if
you increase their value +1, they get to 0.

For signed integer types like short, the behaviour is undefined. In your
case it happens to wrap around, but it could provide some other trash
value, or something else could happen.
ISO C provides a header file <limits.hthat provides the maximum values
for each integer type. You can check the web for more info on <limits.h>.
Jun 27 '08 #15
Added some info:

Ioannis Vranos wrote:
Gio wrote:
>>What compiler and version are you using?
I am using Aztec-C. Its a version of C that's pretty close to but not
quite ANSI C.


What is the name and version of your operating system? Perhaps we can
help you get a more decent compiler.
>>%hd did not work? If it didn't, use %d and use the following code
instead:
Well.. it didn't give me any errors, but it just printed the same values
as %d would.

%hd is the proper format specifier for shorts. %d is for ints, %ld is
for longs. You should use %hd for shorts.
>Output:

i = 32767
i = -32768
i = -32767

What it looks like to me is that it's turning over, like an odometer.


Exactly, in your case it wraps around. You reach the maximum positive
value, and then it goes to the least negative value.

In C, it is guaranteed that all unsigned integer types wrap around after
they reach their maximum value, that is after their maximum value, if
you increase their value +1, they get to 0.

For signed integer types like short, the behaviour is undefined. In your
case it happens to wrap around, but it could provide some other trash
value, or something else could happen.
ISO C provides a header file <limits.hthat provides the maximum values
==and minimum values for each integer type. You can check the web for
more info on <limits.h>.
Jun 27 '08 #16
On Apr 20, 7:34*am, Ioannis Vranos What is the name and version of
your operating system? Perhaps we can
help you get a more decent compiler.
You have never used a more decent compiler since one has never been
written.

Many I think are equal for their respective purposes and Walter
Bright's Digital Mars comes to mind.

Having said that, if you do find a more decent C compiler for the
Apple IIe running ProDOS 8 with better libraries and linking options
and the use of overlays and auxilliary memory, inline assembly, etc.
and documentation let us know. I am sure such a thing would have been
written by odin himself.

I am leaving this link again. For a qualitative and quantitative
evaluation and to define "better compiler" or IMO "best compiler":

http://www.clipshop.ca/Aztec/index.htm

Have some fun if you get the chance<g>
Jun 27 '08 #17
On Apr 19, 7:57*pm, Ioannis Vranos <ivra...@nospam.no.spamfreemail.gr>
wrote:
%hd did not work? If it didn't, use %d and use the following code instead:
<snip>

Ioannis, here's the source from the format function in his compiler.
If you are anticipating expected output here is what to expect. The
architecture is 16 bit and addressable to 0xffff. int foo=32768; like
in MS-DOS segmented memory is (signed short) -1

x--- snip ---x

format.c
/* Copyright (C) 1981,1982,1983 by Manx Software Systems */
#include <ctype.h>
#if MPU8080 || MPUZ80
char *_fmtcvt();
#else
static char *
_fmtcvt(ap, base, cp, len)
int *ap; register char *cp;
{
register unsigned long val;
static char digits[]="0123456789abcdef";
if (len == sizeof(long))
val = *(long *)ap;
else if (base 0)
val = *(unsigned *)ap;
else
val = *ap;
len = 0;
if (base < 0) {
base = -base;
if ((long)val < 0) {
val = -val;
len = 1;
}
}
do {
*--cp = digits[(int)(val%base)];
} while ((val /= base) != 0);
if (len)
*--cp = '-';
return cp;
}
#endif

format(putsub, fmt, argp)
register int (*putsub)(); register char *fmt; char *argp;
{
register int c;
union {
int *ip;
char *cp;
char **cpp;
#ifdef FLOAT
double *dp;
#endif
} args;
int charcount;
int rj, fillc;
int maxwidth, width;
int i, k;
char *cp;
auto char s[200];
charcount = 0;
args.cp = argp;
while ( c = *fmt++ ) {
if ( c == '%' ) {
s[14] = 0;
rj = 1;
fillc = ' ';
maxwidth = 10000;
if ((c = *fmt++) == '-') {
rj = 0;
c = *fmt++;
}
if (c == '0') {
fillc = '0';
c = *fmt++;
}
if (c == '*') {
width = *args.ip++;
c = *fmt++;
} else {
for (width = 0 ; isdigit(c) ; c = *fmt+
+)
width = width*10 + c - '0';
}
if ( c == '.' ) {
if ((c = *fmt++) == '*') {
maxwidth = *args.ip++;
c = *fmt++;
} else {
for (maxwidth = 0 ;
isdigit(c) ; c = *fmt++)
maxwidth = maxwidth*10
+ c - '0';
}
}
i = sizeof(int);
if (c == 'l') {
c = *fmt++;
i = sizeof(long);
} else if (c == 'h')
c = *fmt++;
switch ( c ) {
case 'o':
k = 8;
goto do_conversion;
case 'u':
k = 10;
goto do_conversion;
case 'x':
k = 16;
goto do_conversion;
case 'd':
k = -10;
do_conversion:
cp = _fmtcvt(args.cp, k, s+14, i);
args.cp += i;
break;
case 's':
i = strlen(cp = *args.cpp++);
goto havelen;
#ifdef FLOAT
case 'e':
case 'f':
case 'g':
ftoa(*args.dp++, s, maxwidth==10000?
6:maxwidth, c-'e');
i = strlen(cp = s);
maxwidth = 200;
goto havelen;
#endif
case 'c':
c = *args.ip++;
default:
*(cp = s+13) = c;
break;
}
i = (s+14) - cp;
havelen:
if ( i maxwidth )
i = maxwidth;
if ( rj ) {
if ((*cp == '-' || *cp == '+') &&
fillc == '0') {
--width;
if ((*putsub)(*cp++) == -1)
return -1;
}
for (; width-- i ; ++charcount)
if ((*putsub)(fillc) == -1)
return -1;
}
for ( k = 0 ; *cp && k < maxwidth ; ++k )
if ((*putsub)(*cp++) == -1)
return -1;
charcount += k;
if ( !rj ) {
for (; width-- i ; ++charcount)
if ((*putsub)(' ') == -1)
return -1;
}
} else {
if ((*putsub)(c) == -1)
return -1;
++charcount;
}
}
return charcount;

}
x--- snip ---x

Jun 27 '08 #18
Richard Heathfield wrote:
Gio said:
Expand|Select|Wrap|Line Numbers
  1.  
  2.  short i, j;
  3.  
  4.  i = -32768;
  5.  j = -i;
  6.  
  7.  printf("%d", j);
  8.  
  9.  
...
Okay, so i = -32768, and that's a problem right there,
because it's outside the minimum range for short int,
which is -32767 to +32767. Implementations are free to
provide wider ranges, but are not forced to. I *guess*
that your implementation actually supports -32768 to
+32767. If I'm right, then what's happening is that
the program is trying to assign -(-32768), which is
+32768, into an object that can't support a value that
high. The result is undefined,
Yes, but not for the reasons you describe. The negation
of the short value -32768 may overflow, if INT_MAX <
32768; that is the UB. If there is no overflow, then the
value on assignment (with implicit conversion to short)
is AFAIK implementation-defined under C89 (3.2.1.2).
It's only (effectively) UB under C99 because an
implementation-defined signal may be raised.

--
Peter
Jun 27 '08 #19
Keith Thompson wrote:
...
The statement

i = -32768;

(where i is of type short) will work as long as SHRT_MIN is -32768 or
less (i.e., it can fail only if the range of short is exactly -32767
to +32767). The constant 32768 is of type short, int, or long,
whichever is the first in which it will fit.
It can't be 'short'. Selection of type for integral constant in C begins with
'int' and goes up from there. On a system with more than 16-bit 'int', it's
'int' that will be selected.
Negating it yields a
value of the same type, which cannot overflow, so you have an
expression of some signed integral type with the value -32768.

Assigning this to i causes it to be converted to short; this can fail
only if, as mentioned above, short's range is exactly -32767 to
+32767 (which is unusual for modern systems).

Now in this statement:

j = -i;

if short is 16 bits, the the unary "-" will overflow.
Not necessarily. Type 'short' will not be used directly in value context. It
will be promoted to 'int' first. So, whether the '-' itself will overflow or not
depends on the properties of 'int', not on the properties of 'short'. And,
again, on a system with more than 16-int 'int' it will not overflow. The
overflow might take place during the attempt to assign the result back to 'short'.

In other words, if the range of 'int' is wider than the range of 'short' on that
particular system, the behavior of these two assignments will be essentially the
same: a successful '-' followed by a potentially overflowing assignment. If the
range of 'int' is the same as the range of short, then the behavior would be
different (as you describe). The point is that it all depends on the properties
of 'int', not on the properties of 'short'.

--
Best regards,
Andrey Tarasevich
Jun 27 '08 #20
Walter Roberson wrote:
...
C parses -32768 as the unary minus operation applied to
32678 -- and by previous assumption, 32768 is greater than
the maximum signed short.
But well within the range of long which is what the constant
32768 will be if INT_MAX < 32768. The subsequent negation
will still be a long, though it may not be in the range of
int or short.
Due to a chain of reasons, it is certain to all work out
for the case of assigning a literal -32768 to a signed
int,
Assuming INT_MIN < -32767, which appeared to be the
case on the OP's implementation.

<snip>

--
Peter
Jun 27 '08 #21
Andrey Tarasevich <an**************@hotmail.comwrites:
Keith Thompson wrote:
>...
The statement

i = -32768;

(where i is of type short) will work as long as SHRT_MIN is -32768 or
less (i.e., it can fail only if the range of short is exactly -32767
to +32767). The constant 32768 is of type short, int, or long,
whichever is the first in which it will fit.

It can't be 'short'. Selection of type for integral constant in C
begins with 'int' and goes up from there. On a system with more than
16-bit 'int', it's 'int' that will be selected.
You're right.
>Negating it yields a
value of the same type, which cannot overflow, so you have an
expression of some signed integral type with the value -32768.

Assigning this to i causes it to be converted to short; this can fail
only if, as mentioned above, short's range is exactly -32767 to
+32767 (which is unusual for modern systems).

Now in this statement:

j = -i;

if short is 16 bits, the the unary "-" will overflow.

Not necessarily. Type 'short' will not be used directly in value
context. It will be promoted to 'int' first. So, whether the '-'
itself will overflow or not depends on the properties of 'int', not on
the properties of 'short'. And, again, on a system with more than
16-int 'int' it will not overflow.
Right again.
The overflow might take place
during the attempt to assign the result back to 'short'.
Yes. But if so, that's an overflowing conversion, which yields an
implementation-define result or (new in C99) raises an
implementation-defined signal; an overflow on a unary "-" with a
signed operand would invoke undefined behavior.
In other words, if the range of 'int' is wider than the range of
short' on that particular system, the behavior of these two
assignments will be essentially the same: a successful '-' followed by
a potentially overflowing assignment. If the range of 'int' is the
same as the range of short, then the behavior would be different (as
you describe). The point is that it all depends on the properties of
int', not on the properties of 'short'.
Thanks for the corrections!

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #22

"Gio" <gi*******@sbcglobal.netwrote in message
news:ZC*****************@nlpi070.nbdc.sbc.com...
Well, I'd like to thank you all for your answers. Not sure that I
understand them, but I shall study them. :)
You need to study "two's complement arithmetic" which is what your compiler
and computer appears to be using (as opposed to "one's complement
arithmetic" or "sign magnitude"). Search for those terms on the internet.
Then the answers will make sense.

Paul
Jun 27 '08 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Dan | last post by:
Is there a python equivalent of this trick in C? Logic_Test ? True_Result : False_Result Example: printf( "you have %i %s", num_eggs, num_eggs > 1 ? "eggs" : "egg" );
134
by: Joseph Garvin | last post by:
As someone who learned C first, when I came to Python everytime I read about a new feature it was like, "Whoa! I can do that?!" Slicing, dir(), getattr/setattr, the % operator, all of this was very...
1
by: TEN TOD PSA | last post by:
you can trick ASP.NET into letting you declare methods with code blocks (how anybody can survive without this i have no idea - in classic asp i haven't written any html outside of a sub/method in 8...
14
by: BGreene | last post by:
I was not going to post this but my someone thought it was funny, Write the shortest c statement that will "exchange" two unsigned ints. in place.
5
by: Alex Nitulescu | last post by:
Hi. Because I'm a beginner in creating controls, I spent more than two *&^#$ hours to create this "login" as a custom control and to make it work properly: ...
4
by: Boni | last post by:
Dear all, Is there some trick to put controls on a particular control but in other thread. Example: A control is a part of bigger application and application thread freezes somtimes. So a...
5
by: Marty | last post by:
Hi, I've read that the if/else statement, or get/set accessor, can be compiled inline by the C# compiler if they are small enough. Have you seen any documentation that 'summarized' all thoses...
24
by: Piyush Agarwal | last post by:
void main { int x; if(x) printf("Hello"); else printf("World"); } What value can be given to x such that the output is "Hello World"?
3
by: Ayaz Ahmed Khan | last post by:
I'm working with the following class heirarchy (I've snipped out the code from the classes): class Vuln: def __init__(self, url): pass def _parse(self): pass
1
by: Jack Black | last post by:
Is there a trick (or is it even possible) to get an xcopy distribution of an app to work on restricted-privilege domain users' workstations? I have the appropriate application properties set in...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.