0

Here is my code:

#include <bits/stdc++.h>
using namespace std;
int main(){
    char a = 129;
    printf("%d", a);
}

OUTPUT:-127
I want to konw how 129 changes to -127.

  • 2
    related/dupe: https://stackoverflow.com/questions/29235436/c-integer-overflow – NathanOliver Jan 19 '23 at 05:11
  • Fun exercise: look up how Two's Complement represents signed numbers, and then map and compare 129 and -127 to an 8-bit space on paper. – mukunda Jan 19 '23 at 05:29

3 Answers3

1

Size of character is 1 byte. By default if not specified char is signed so MSB 1 bit is used to indicate the sign (0 indicate positive number , 1 indicates negative number)

129 in binary is 1000 0001, MSB 1 indicate its negative number. negative number are stored in 2's complement form (which means we first negate/invert the number and then add 1 to get the actual value):

original: 1000 0001

negate : 0111 1110

add 1 : 0111 1111

which gives -127

Going a step further if we define a unsigned char than all 8 bits are used to indicate number value and negative numbers cannot be represented. since range than increases to 255 , 129 can be represented fine as in below code snippet.

Now if we take a negative number for unsigned it value would be the 2's complement representation of that negative number. for example -1 in 2's complement is calculated below:

original: 0000 0001

negate: 1111 1110

add 1: 1111 1111

so we get 255 as shown in below code example.

int main()
{
   char a = 129; // by default its signed char
   unsigned char b = 129;
   char c = -1;
   unsigned char d = -1;

   printf ("sizeof(char) %d %d\n",sizeof(a), sizeof(b));
   printf("%d\n", a);
   printf ("%d\n", b);
   printf ("%d\n", c);
   printf ("%d\n", d);
}

output:

sizeof(char) 1 1

-127

129

-1

255

  • *"Though size of char varies on the platform but on my system its 1 byte... "* No, size of `char` is always `1` byte in C++. – Jason Jan 19 '23 at 11:57
  • 1
    Note also that `char` in C++ can be either signed or unsigned by default. But it is always a separate type, distinct from both `signed char` and `unsigned char`. – Adrian Mole Jan 19 '23 at 14:19
  • “original: 1000 0001 negate : 0111 1110” why the first ‘1’ is changed to ‘0’?As i konw,the sign bits is unchanged when negate – gameplayer47 Jan 23 '23 at 08:59
  • No it includes the sign bit also. plz check https://www.tutorialspoint.com/two-s-complement – Ravneet Singh Jan 30 '23 at 07:26
0

The type is signed type. The signed 'char' ranges from -128 to 127. When you assign 129 to it, it is two (129-127) numbers above maximum capacity. So after max capacity it started counting from minimum capacity, and observed -127 printing.

To see 129, use unsigned char, whose range is 0 to 255.

Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
  • 129:10000001 127:1111111 how it changes? – gameplayer47 Jan 19 '23 at 05:22
  • Note the signness of `char` is not specified, and can be either signed or unsigned. However, based on the result, `char` is signed for OP. Related: [Is char signed or unsigned by default?](https://stackoverflow.com/questions/2054939/is-char-signed-or-unsigned-by-default) – Ranoiaetep Jan 19 '23 at 05:24
  • @gameplayer47 it's turning into negative 127; you are comparing against positive 127 there – mukunda Jan 19 '23 at 05:39
  • @gameplayer47 the most significant bit represents sign in case of signed bits. – Pavan Chandaka Jan 19 '23 at 05:45
0

It is a little bit of code you have, but you can learn a lot from it already. One is to never ignore compiler warnings :)

Here is some modified code to help you explain things :

// #include <bits/stdc++.h> // NO never use this it is NOT a standard header file 
// using namespace std; // NO never use using namespace std; (using namespace is not recommended at all in big projects).

#include <iostream> // for console output
#include <format>   // C++20 replacement for printf
#include <limits>   // get information on maximum and minimum values

int main() 
{
    // NEVER ignore your compiler warnings. The compiler already warns value will not fit!!!
    // \temp\main.cpp(11,14): warning C4309: 'initializing': truncation of constant value
    char a = 129; // a signed char will not hold this.
    // printf("%d", a); // printf can be used, but is considered "unsafe" (can lead to buffer overflows)

    std::cout << std::format("the value of your number {}\n", a); // C++20

    // in the following code the casts are necessary to convert from char to a size value (otherwise output will show control characters)
    std::cout << "the minimum value in a char = " << static_cast<std::size_t>(std::numeric_limits<char>::min()) << "\n"; 
    std::cout << "the maximum value in a char = " << static_cast<std::size_t>(std::numeric_limits<char>::max()) << "\n";

    std::cout << "the minimum value in an unsigned char = " << static_cast<std::size_t>(std::numeric_limits<unsigned char>::min()) << "\n";
    std::cout << "the maximum value in an unsigned char = " << static_cast<std::size_t>(std::numeric_limits<unsigned char>::max()) << "\n";

    return 0;
}

So you have a choice to make, use numbers <129 or change to unsigned char. or std::uint8_t

Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19