The Tilde Operator in C

The tilde operator in C

The ~ operator is bitwise NOT, it inverts the bits in a binary number:

NOT 011100
= 100011

What does tilde(~) operator do?

The ~ operator in C++ (and other C-like languages like C and Java) performs a bitwise NOT operation - all the 1 bits in the operand are set to 0 and all the 0 bits in the operand are set to 1. In other words, it creates the complement of the original number.

For example:

10101000 11101001 // Original  (Binary for -22,295 in 16-bit two's complement)
01010111 00010110 // ~Original (Binary for 22,294 in 16-bit two's complement)

In your example, ch=~((ch^i)) performs a bitwise NOT on the bitwise XOR of ch and i then assigns the result to ch.

The bitwise NOT operator has an interesting property that when applied on numbers represented by two's complement, it changes the number's sign and then subtracts one (as you can see in the above example).

You may want become familiar with the different operators of the C++ language since it is difficult to search for operators on search engines. Better yet, you can get a good C++ book which will tell you about the C++ operators.

printf tilde operator in c

The ~ operator simply inverts all bits in a number.

On most modern compilers, int is 32 bits in size, and a signed int uses 2's complement representation. Which means, among other things, that the high bit is reserved for the sign, and if that bit is 1 then the number is negative.

0 and 7 are int literals. Assuming the above, we get these results:

  • 0 is bits 00000000000000000000000000000000b

    = 0 when interpreted as either signed int or unsigned int

  • ~0 is bits 11111111111111111111111111111111b

    = -1 when interpreted as signed int

    = 4294967285 when interpreted as unsigned int

  • 7 is bits 00000000000000000000000000000111b

    = 7 when interpreted as either signed int or unsigned int

  • ~7 is bits 11111111111111111111111111111000b

    = -8 when interpreted as signed int

    = 4294967288 when interpreted as unsigned int

In your printf() statements, %d interprets its input as a signed int, and %u interprets as an unsigned int. This is why you are seeing the results you get.

tilde operator query in C working differently

The bitwise negation will not result in 0101. Note that an int contains at least 16 bits. So, for 16 bits, it will generate:

 a = 0000 0000  0000 1010
~a = 1111 1111 1111 0101

So we expect to see a large number (with 16 bits that would be 65'525), but you use %d as format specifier. This means you interpret the integer as a signed integer. Now signed integers use the two-complement representation [wiki]. This means that every integers where the highest bit is set, is negative, and furthermore that in that case the value is equal to -1-(~x), so -11. In case the specifier was %u, then the format would be an unsigned integer.

EDIT: like @R. says, %d is only well defined for unsigned integers, if these are in the range of the signed integers as well, outside it depends on the implementation.

Tilde operator in C

%u expects an unsigned int; if you want to print an unsigned short int, use %hu.

EDIT

Lundin is correct that ~i will be converted to type int before being passed to printf. i is also converted to int by virtue of being passed to a variadic function. However, printf will convert the argument back to unsigned short before printing if the %hu conversion specifier is used:

7.21.6.1 The fprintf function
...

3 The format shall be a multibyte character sequence, beginning and ending in its initial
shift state. The format is composed of zero or more directives: ordinary multibyte
characters (not %), which are copied unchanged to the output stream; and conversion
specifications, each of which results in fetching zero or more subsequent arguments,
converting them, if applicable, according to the corresponding conversion specifier, and
then writing the result to the output stream.

...

7 The length modifiers and their meanings are:

...

h Specifies that a following d, i, o, u, x, or X conversion specifier applies to a
short int or unsigned short int argument (the argument will
have been promoted according to the integer promotions, but its value shall
be converted to short int or unsigned short int before printing
);
or that a following n conversion specifier applies to a pointer to a short
int
argument.

Emphasis mine.

So, the behavior is not undefined; it would only be undefined if either i or ~i were not integral types.

Tilde '~' operator on _Complex, what does it do? Is it an extension?

This is in fact a gcc extension, documented in section 6.11 of the gcc manual:

The operator ~ performs complex conjugation when used on a value with a complex type. This is a GNU extension; for values of floating type, you should use the ISO C99 functions conjf, conj and conjl, declared in <complex.h> and also provided as built-in functions by GCC.

If you compile with the -pedantic flag, you'll get a warning for this:

x1.c: In function ‘main’:
x1.c:6:29: warning: ISO C does not support ‘~’ for complex conjugation [-Wpedantic]
printf("%f,%f\n", creal(~a), cimag(~a));
^
x1.c:6:40: warning: ISO C does not support ‘~’ for complex conjugation [-Wpedantic]
printf("%f,%f\n", creal(~a), cimag(~a));

What does ~(tilde) means before scanf function in c++?

I found tilde can be used for either destructor or binary negation but it doesn't look like both.

It's the bitwise NOT operator applied to the return value of scanf() as you mentioned latter.

And the code doesn't work without tilde.

As @Mukul Gupta explained in their comment:

scanf returns the number of values it scanned successfully or EOF
if it reaches the end of file. EOF is a macro that represents a
negative value. On most platforms, the value of EOF is (int) -1.
In this case, taking 1's complement of -1, will make the value as 0
and is used to break from the loop.

In the C language, what does return ~0 mean?

~ is a bitwise not/complement, aka it changes all 0's to 1's and vice-versa. ~0 is a value with all bits set to 1.

Meaning of ~ (tilde) symbol in C++?

It is the destructor.
It gets called when you destroy (reaching end of scope, or calling delete to a pointer to) the instance of the object.



Related Topics



Leave a reply



Submit