Python
Tilde Operator
Bitwise Operations
Python Programming
Python Tips

The tilde operator in Python

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In Python, the tilde operator ~ performs bitwise inversion on integers. It is often mistaken for logical negation, but it has nothing to do with boolean truth in the usual sense. Understanding ~ means understanding bitwise complement, two's-complement arithmetic, and the difference between Python’s arbitrary-precision integers and fixed-width machine integers.

Core Sections

What ~x means mathematically

For an integer x, Python evaluates ~x as -(x + 1).

python
for n in [0, 1, 5, -3]:
    print(n, ~n, -(n + 1))

This identity explains why ~5 becomes -6. Many developers expect a positive inverted bit pattern such as they might see in an 8-bit system, but Python integers do not have a fixed width by default.

Why the result looks surprising

In hardware-oriented thinking, you might imagine 5 as 00000101 and expect inversion to give 11111010, which is 250 in unsigned 8-bit form. Python does not automatically choose that 8-bit width. Instead, it treats the value as an integer with conceptually unbounded precision and applies two's-complement arithmetic rules.

That is why:

python
print(~5)

prints -6 rather than 250.

If you need a fixed-width interpretation, you must apply a mask explicitly.

python
x = 5
print(~x)
print((~x) & 0xFF)

The second line gives the 8-bit-style result.

~ is not the same as not

A very common bug is confusing bitwise inversion with logical negation.

python
print(not 5)
print(~5)

not 5 returns False because it is a boolean operation. ~5 returns -6 because it is an arithmetic bitwise operation.

They solve different problems:

  • 'not is for truth values and conditions'
  • '~ is for bit patterns and numeric masks'

If you use ~ in ordinary conditional logic when you meant not, the result is usually wrong and sometimes very confusing.

A common use: clearing bits with masks

The tilde operator is useful in bitmask work, especially when clearing a flag.

python
1READ = 0b001
2WRITE = 0b010
3EXEC = 0b100
4
5perm = READ | WRITE | EXEC
6perm = perm & ~WRITE
7
8print(bin(perm))

This is the classic “clear this bit” pattern. The operator inverts the target mask, and the bitwise and keeps everything except the bit being removed.

NumPy uses ~ element-wise

In NumPy, ~ works element-wise on boolean and integer arrays. That makes it useful for vectorized logic and mask manipulation.

python
1import numpy as np
2
3flags = np.array([True, False, True])
4print(~flags)
5
6nums = np.array([1, 2, 3], dtype=np.int32)
7print(~nums)

This is different from scalar Python not, which does not operate element-wise over arrays. That is why ~ is common in NumPy mask code.

Be explicit when width matters

Any code that interacts with bytes, protocols, checksums, or device registers should make width explicit. Otherwise the complement may be mathematically correct in Python but wrong for the intended binary format.

python
1def invert_byte(x: int) -> int:
2    return (~x) & 0xFF
3
4
5print(invert_byte(0b00001111))

That explicit mask communicates the real contract of the function far better than a bare ~x does.

Common Pitfalls

  • Confusing ~ with not leads to arithmetic results where boolean logic was intended.
  • Expecting Python to use a fixed machine width automatically produces surprising negative results such as ~5 == -6.
  • Forgetting to mask after inversion in byte-oriented code breaks protocol and hardware-style logic.
  • Writing dense bitwise expressions without helper functions or comments makes review and debugging much harder.
  • Assuming NumPy and scalar Python behave identically can cause mistakes when switching between array masks and normal conditionals.

Summary

  • In Python, ~x means bitwise inversion and is equivalent to -(x + 1).
  • The result is often negative because Python integers are not fixed-width by default.
  • Use masks such as & 0xFF when you need an 8-bit or other fixed-width interpretation.
  • Keep ~ distinct from the boolean operator not.
  • In bitmask and NumPy code, ~ is useful, but it should be used with clear width and intent.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.