1

Recently in my Institute I was given a code and was asked to find out the answer. The code looks like this.

#include <stdio.h>
int main()
{
    char ch=500;
    printf("%d\n",ch);
}

The output will come as -12

My question is: How can I calculate the value for this kind of code? Is there any formula or process for finding the values?

6
  • 1
    Did the compiler not warn? When I compile this code (gcc) I get warning: implicit conversion from 'int' to 'char' changes value from 500 to -12 [-Wconstant-conversion] Commented Feb 9, 2016 at 7:23
  • As far as I know this is not syntax error.. this is a valid expression.. But how to calculate the value I don't understand... Commented Feb 9, 2016 at 7:26
  • 1
    Ah, I'm actually using clang. Try the "-Wall" option to gcc. Commented Feb 9, 2016 at 7:26
  • 2
    Assuming 8-bit characters (so CHAR_BIT == 8 in <limits.h>), then characters can hold 256 different values. The plain char type can have the same range as unsigned char (0..255) or the same range as signed char (-128..+127, assuming two's-complement). On your machine, it appears that plain char is signed. When the value 500 is stored, the extra (more significant) bit(s) are removed; the least significant 8 bits are stored in the variable — as either +244 or -12 (-12 for your system). When passed to printf(), the value is converted to (signed) int. Commented Feb 9, 2016 at 7:28
  • 1
    Now if the person who asked you thinks the behavior of the code is well-defined, they probably should step down from the teacher role and become student. Crappy programming teachers is a serious plague for the software industry. Commented Feb 9, 2016 at 7:48

4 Answers 4

3

The code is syntactically correct but not doing what you think. As Paul Hankin is suggesting your compiler should give you a warning as you are trying to set a number that does not fit into a char in a char variable.

A char is 1 byte so it can store a number up to 127 if signed or 255 if unsigned. The value overflows and only the lower 8 bits are taken into account.

500 = 0b111110100

Take only the lower 8 bits: 0b11110100

The MSB is 1 so it's negative number.

1-complement plus 1 is 0b00001100 which is 12

That's why you get -12.

Replacing it by a short or an int should correctly print 500.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanksss.. This has been a great help... :)
2

You can't know, unless you know the specifics of the given system.

char is typically only 8 bits wide and can't hold the value of 500. Furthermore, the char type is unsuitable for storing integer values, since it has implementation-defined signedness.

Meaning you can't know if it can contain values from 0 to 255 or from -128 to 127 (two's complement). It can even in theory have other constrains and other signedness formats.

Also, the conversion from a large unsigned integer to a smaller signed one is implementation-defined.


I would guess that your specific system has signed 8 bit char type and two's complement signedness. The raw value of 500 is 0x1F4. Upon initialization, your particular compiler will truncate this to fit an 8 bit variable, meaning you end up with only the least significant byte, 0xF4. Since you have an 8 bits signed variable in two's complement format, 0xF4 equals -12.

(The implicit type promotion done by printf preserves the sign.)

None of this behavior is guaranteed across different systems.

Needless to say, the code is completely non-portable. You should not write code like this, which heavily relies on numerous forms of poorly defined behavior.

Comments

0

here in this code ch is signed character type and seems its 8-bit ascii code... so its range is from -128 to +127 (total 256)...

now lets cycle over this ascii range starting from 0 to 127 then -128 to 0 and so... total value of integer number is 500

from 0 to 127 and -128 to 0 (whole circle), left integer value is 500-256 = 244.

from 0 to 127, left integer value is 244-128=116. from -128 to -12, left integer value is 116-116=0.

so after counting all 500 we are at -12 of ascii range....

"sorry for long and non-mathematical explanation....effort is to make you understand"

Comments

-3

When using char data types to encode integers, the char values go from -128 to 127. The value is overflowing.

500 - 127 = 373
373 - 128 = 245
245 - 127 = 118
118 - 128 = -10

Since we are passing over 0 twice and that counts, it give us -12. If you try to print the character you will see that it is invalid there is no -12 literal. You can also check man ascii

3 Comments

Eh? What's this strange calculation? The conversion from large unsigned to small signed type typically just means that the compiler will chop off excess bytes and leave you with the ls byte.
It's just another way to calculate the conversion.
I don't see the logic. Why do you subtract by 127 sometimes and 128 other times? Also what is "we are passing over 0 twice and that counts" supposed to mean?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.