Question

M

Mateusz_madi

char c= -1;
int x;
x=c;
printf("%d", x);

Result:
-1

Why it is -1? How -1 is represented in char in binary format?

Regards,

Mateusz
 
B

Ben Pfaff

Mateusz_madi said:
char c= -1;
int x;
x=c;
printf("%d", x);

Result:
-1

Why it is -1? How -1 is represented in char in binary format?

Presumably 'char' is a signed type. It shouldn't be surprising
that a signed integer type should be able to store -1.

The most common way to store -1 as a binary integer is with all
1-bits.
 
K

Keith Thompson

Mateusz_madi said:
char c= -1;
int x;
x=c;
printf("%d", x);

Result:
-1

Why it is -1? How -1 is represented in char in binary format?

Caution: The following provides, to quote John Hodgman's book title,
More Information Than You Require.

It printed -1 because you assigned -1 to c, then assigned the value
of c to x, then printed the value of x. I'm surprised that you
find this surprising.

Another interesting question is why it *wouldn't* be -1.

The type "char" (I'll call it "plain char") can be either signed
or unsigned. Either it has the same representation as signed char,
or it has the same representation as unsigned char -- though they're
still three distinct types.

Apparently plain char is signed in your implementation (which is
very common but not universal).

If plain char were an unsigned type, then the initialization
would convert the value -1 from int to char. The rules of
signed-to-unsigned conversion are such that the result is CHAR_MAX-1,
and if plain char is a signed type, then CHAR_MAX-1 is likely to
be 255.

The assignment ``x=c'' then converts the value 255 from char to int.
Since int can (probably) represent the entire range of char, the
conversion yields the same value in the new type, so x gets the
value 255, which is then printed. You can see what would happen
by modifying your program so c is declared as unsigned char rather
than char.

You'll note that several of my statements were qualified with
"likely" or "probably". The number of bits in a char (i.e., in
a byte) is the value of CHAR_BIT, which is defined in <limits.h>
The standard requires CHAR_BIT to be at least 8, but it can legally
be larger.

And if CHAR_BIT is at least 16, then it's possible that int is only
as wide as char. In that case, if plain char is an unsigned type,
then (signed) int can't represent all its values, which affects
the rules for converting from char to int.

You're not likely to run into any systems like this (I never have),
though I understand that DSPs (Digital Signal Processors) commonly
have CHAR_BIT set to 16 or 32.

As for how -1 is represented in char in binary format, there's
probably no good reason for you to care. C's conversion rules
are defined in terms of values, not representations. But on any
system you're likely to encounter, storing -1 in a char (which will
store -1 if char is signed, or CHAR_MAX, probably 255, if char is
unsigned) will *probably* set all the bits to 1. (There are other
possible represntations for signed integers, namely 2's-complement
and 1s'-complement, but few if any modern systems use them.)

And if you got this far without falling asleep, I'm impressed. :cool:}
 
M

Mateusz_madi

Presumably 'char' is a signed type.  It shouldn't be surprising
that a signed integer type should be able to store -1.

The most common way to store -1 as a binary integer is with all
1-bits.

Yes, char is signed type but mayby it was wrong asked question I ment:

if char is 8 bit long so -1 is : 1111 1111
and i assign it to int which let's say is 32 bit long, shoudn't int
look like: 0000 0000 0000 1111 ?

Regards,
Mateusz
 
B

Ben Pfaff

Mateusz_madi said:
if char is 8 bit long so -1 is : 1111 1111
and i assign it to int which let's say is 32 bit long, shoudn't int
look like: 0000 0000 0000 1111 ?

No. Type conversions in C preserve value, not bit pattern. If
you assign -1, of any integer type, to an object with any other
signed integer type, the destination will have value -1.

I don't understand how you'd come up with the bit pattern that
you suggested anyway. You wrote a total of 16 bits (not 32), and
you only made 4 of them 1-bits (not 8).
 
J

Joe Pfeiffer

Ben Pfaff said:
No. Type conversions in C preserve value, not bit pattern. If
you assign -1, of any integer type, to an object with any other
signed integer type, the destination will have value -1.

To amplify (so I'm not disagreeing with Ben here), in general if a
signed value is copied into a larger word, the value of the integer is
preserved if the sign bit is extended across all the new high-order
bits. So, since your sign bit was a 1, all the new bits are 1's as
well. This is called "sign-extending".
I don't understand how you'd come up with the bit pattern that
you suggested anyway. You wrote a total of 16 bits (not 32), and
you only made 4 of them 1-bits (not 8).

I'll guess he meant

0000 0000 0000 0000 0000 0000 1111 1111

Sign-extended, he would actually get

1111 1111 1111 1111 1111 1111 1111 1111

Something else that ought to be noted is that char can be either signed
or unsigned (it's implementation-dependent). If he wants it to be
signed, he should use a signed char.
 
K

Keith Thompson

Joe Pfeiffer said:
To amplify (so I'm not disagreeing with Ben here), in general if a
signed value is copied into a larger word, the value of the integer is
preserved if the sign bit is extended across all the new high-order
bits. So, since your sign bit was a 1, all the new bits are 1's as
well. This is called "sign-extending".


I'll guess he meant

0000 0000 0000 0000 0000 0000 1111 1111

Sign-extended, he would actually get

1111 1111 1111 1111 1111 1111 1111 1111

Something else that ought to be noted is that char can be either signed
or unsigned (it's implementation-dependent). If he wants it to be
signed, he should use a signed char.

Sign-extension preserves the value if negative numbers are
represented using 2's-complement. If the implementation uses either
1s'-complement or sign-and-magnitude, then it needs to use some other
method to preserve the value (I'm too lazy to work out the details).

The point is that the standard requires the value to be preserved,
without regard to how either the source or the target is represented,
or how much extra work the implementation has to go through to get
the required result.

A 2's-complement representation makes some operations easier,
which is why it's used so often.
 
B

Ben Pfaff

Keith Thompson said:
Sign-extension preserves the value if negative numbers are
represented using 2's-complement. If the implementation uses either
1s'-complement or sign-and-magnitude, then it needs to use some other
method to preserve the value (I'm too lazy to work out the details).

I think that ones' complement sign extension is the same as two's
complement sign extension.
 
M

Morris Keesan

....
Yes, char is signed type but mayby it was wrong asked question I ment:

if char is 8 bit long so -1 is : 1111 1111
and i assign it to int which let's say is 32 bit long, shoudn't int
look like: 0000 0000 0000 1111 ?

int i = -1;
long int l = i;

assert(sizeof(long) > sizeof(int));
printf("%ld\n", l);

Would it surprise you if this printed -1?
 
B

Ben Pfaff

Morris Keesan said:
int i = -1;
long int l = i;

assert(sizeof(long) > sizeof(int));
printf("%ld\n", l);

What is the value of the assertion? Every signed type is capable
of holding -1.
 
K

Kleuskes & Moos

I think that ones' complement sign extension is the same as two's
complement sign extension.

I think you would end up with -0, if you operated under that
assumption.
 
J

Joe Pfeiffer

Keith Thompson said:
Sign-extension preserves the value if negative numbers are
represented using 2's-complement. If the implementation uses either
1s'-complement or sign-and-magnitude, then it needs to use some other
method to preserve the value (I'm too lazy to work out the details).

1's complement also uses sign-extending. Sign-magnitude would move the
sign bit out to the new MSB and fill in between with 0s.
The point is that the standard requires the value to be preserved,
without regard to how either the source or the target is represented,
or how much extra work the implementation has to go through to get
the required result.

He was asking about bit patterns, so answering his question seemed
reasonable. Besides, I last worked on a 1's complement machine in the
mid 1970s, and have never seen a sign-magnitude computer, so I don't
really regard those cases as significant.
 
J

Joe Pfeiffer

Kleuskes & Moos said:
I think you would end up with -0, if you operated under that
assumption.

Eight bit 1's complement -1 is 1111 1110. 1111 1111 would indeed be -0,
but that's not the bit pattern he would have started with.
 
P

Peter Nilsson

...
A 2's-complement representation makes some operations easier,

And some harder.
which is why it's used so often.

Well, I'd say it's popularity is more akin to VHS v BETA. VHS
certainly wasn't superior, but it was cheaper and more popular.
 
J

J. J. Farrell

Ben said:
What is the value of the assertion? Every signed type is capable
of holding -1.

Since the OP's puzzlement was around value being preserved on assigning
from a smaller integer type to a larger one, the example wouldn't have
much relevance in cases where long and int are the same size.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,952
Messages
2,570,111
Members
46,691
Latest member
Wilhemina5

Latest Threads

Top