2

I would like to know what the ~ operand does with a char. Example code: the output is -1 if var="a".

int ret (char var)
{
   int x;
   x=var|~var;
   return x;
}
int main()
{
  printf("%d",ret("a"));
  return 0;
}

I dont understand why it returns -1

pm100
  • 48,078
  • 23
  • 82
  • 145
csjr
  • 116
  • 4
  • 12
  • 3
    Do you know what the `~` operator does? – Oliver Charlesworth Jul 09 '14 at 19:47
  • Operator ~ in theory, puts a 0 where is a 1, and a 1 where is a 0. – csjr Jul 09 '14 at 19:49
  • 5
    ASCII(a) --> 97. 97 + -98 --> -1. `-37` looks strange. – chux - Reinstate Monica Jul 09 '14 at 19:49
  • @chux could you explain a little bit more? – csjr Jul 09 '14 at 19:50
  • 1
    Are you certain `char var = 'a';` in a windows based pc outputs -37? – chux - Reinstate Monica Jul 09 '14 at 19:53
  • 1
    I'm very surprised that you'd get `-37` on Windows. That's what I'd expect for `char var = '$';`. – Keith Thompson Jul 09 '14 at 19:53
  • Double check your Windows code, you may defined `var` as `char var = "a";`, which may get such strange result. –  Jul 09 '14 at 20:08
  • The `-98` is easy to explain, `-37` is not. `'a'` has the ASCII code of 97 which is certainly the value assigned via `char var = 'a';`. `~var` takes the bit-wise inverse. Since `var`, a `char` is likely smaller is _size_ than `int`, `var` is converted (or promoted) - always fuzzy on this) to an `int`. The result is still 97 or 0b01100001, but likely 32-bits wide (maybe 64 or 16, etc.) 0b00000000_00000000_00000000_01100001. Now `~` is applied, giving an `int` with something like a`0b11111111_11111111_11111111_10011110`. This value is passed to `printf()`. – chux - Reinstate Monica Jul 09 '14 at 20:58
  • Given a typical 2's Compliment notation, the result is -98. – chux - Reinstate Monica Jul 09 '14 at 20:58
  • 3
    This question appears to be off-topic because it cannot readily be reproduced and OP has not supplied needed clarification. – chux - Reinstate Monica Jul 09 '14 at 21:18
  • i dont see that this is 'off topic' it asks what an operator (slightly obscure one) does. This is perfectly valid. That the question is a little messy is different – pm100 Jul 09 '14 at 23:23
  • The question is about type promotion. char does not exist as an `expression` , so it is promoted to an int. – wildplasser Jul 09 '14 at 23:53
  • Why was this closed? Perhaps not a very good question, but it's most certainly about programming. – Tom Zych Jul 09 '14 at 23:58
  • When `ret("a")` is called, it passed the _address_ of the string `"a"`. Within `int ret (char var)`, `var` takes on a partial value of that address. It is partial as an address certainly will not fit in `char`. Strongly suspect you meant `ret(`a`)`. (single quote vs double quote.) Please clarify your interest. – chux - Reinstate Monica Jul 11 '14 at 02:20
  • Regardless of what value is in `var`, `x = var | ~var;` will certainly result in `-1`. `~var` result in a signed extension of the bit-wise negation of `var`. So if `var` is 0b01100001 (and int is 32-bit), then `~var` is 0x11111111_11111111_11111111_10011110. The `|` of these 2 is then `0x11111111_11111111_11111111_11111111` and that bit pattern is returned. As `int` is very often coded as 2's complement, this bit pattern prints out as `-1`. – chux - Reinstate Monica Jul 11 '14 at 02:31

2 Answers2

2

First "a" and 'a' are different. "a" passes the address of string array "a" and 'a' passes the char a. So you need to modify the code as

printf("%d",ret('a'));

Once modified, var is 97 which is 0x00000061 and ~var is -98 which is 0xffffff9e.

0x00000061 | 0xffffff9e will be 0xffffffff that will be '-1' by Two's complement.

If you want 0xffffffff, use %x instead as

printf("0x%x",ret('a'));
emesday
  • 6,078
  • 3
  • 29
  • 46
1

The ~ operator is the negation operator which has the identity -x-1. There is both a logical (bitwise) negation and an arithmetic negation. C implements an arithmetic negation with the ~. Take for example x=5in binary:

x = 5

The the ~ operation would have the following effect:

~x = -5-1 = -6

In your case 'a' is 97 or 01100001, therefore

~a = -97-1  (or -98)

Sorry for the confusion

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85