Operators in Programming

Table of Contents

A Complete Guide to Programming Operators


Table of Contents

  1. Introduction to Operators
  2. Arithmetic Operators
  3. Assignment Operators
  4. Comparison Operators
  5. Logical Operators
  6. Bitwise Operators
  7. String Operators
  8. Type Operators
  9. Ternary/Conditional Operator
  10. Operator Precedence
  11. Operator Overloading
  12. Special Operators
  13. Short-Circuit Evaluation
  14. Common Pitfalls
  15. Interview Questions

Introduction to Operators

Operators are special symbols or keywords that perform operations on operands (values or variables). They are the building blocks of expressions and allow us to manipulate data, make decisions, and control program flow.

What Are Operators?

An operator is a symbol that tells the compiler or interpreter to perform a specific mathematical, logical, or relational operation.

// Basic operator examples
let sum = 5 + 3;        // '+' is an arithmetic operator
let isEqual = (10 == 10); // '==' is a comparison operator
let result = (age > 18) && (hasLicense); // '&&' is a logical operator

Types of Operators by Operand Count

TypeDescriptionExamples
UnaryOperates on one operand-5, !true, ++x
BinaryOperates on two operandsa + b, x && y
TernaryOperates on three operandscondition ? a : b

Arithmetic Operators

Arithmetic operators perform mathematical calculations on numeric values.

Basic Arithmetic Operators

# Python
a = 10
b = 3
print(a + b)   # Addition: 13
print(a - b)   # Subtraction: 7
print(a * b)   # Multiplication: 30
print(a / b)   # Division: 3.333...
print(a // b)  # Floor division: 3
print(a % b)   # Modulus (remainder): 1
print(a ** b)  # Exponentiation: 1000
// JavaScript
let a = 10;
let b = 3;
console.log(a + b);   // 13
console.log(a - b);   // 7
console.log(a * b);   // 30
console.log(a / b);   // 3.333...
console.log(a % b);   // 1
console.log(a ** b);  // 1000 (ES7+)
// Java
int a = 10;
int b = 3;
System.out.println(a + b);   // 13
System.out.println(a - b);   // 7
System.out.println(a * b);   // 30
System.out.println(a / b);   // 3 (integer division)
System.out.println(a % b);   // 1

Increment and Decrement Operators

// JavaScript
let x = 5;
// Post-increment: returns value, then increments
console.log(x++);  // 5
console.log(x);    // 6
// Pre-increment: increments, then returns value
console.log(++x);  // 7
console.log(x);    // 7
// Post-decrement
console.log(x--);  // 7
console.log(x);    // 6
// Pre-decrement
console.log(--x);  // 5
# Python (no ++/-- operators)
x = 5
x += 1  # Instead of x++
x -= 1  # Instead of x--

Unary Plus and Minus

// JavaScript
let num = "42";
let negative = -10;
console.log(+num);    // 42 (converts to number)
console.log(-negative); // 10 (negation)
console.log(-num);    // -42

Assignment Operators

Assignment operators assign values to variables.

Basic Assignment

// JavaScript
let x = 10;  // Basic assignment

Compound Assignment Operators

# Python
x = 10
x += 5   # x = x + 5   (15)
x -= 3   # x = x - 3   (12)
x *= 2   # x = x * 2   (24)
x /= 4   # x = x / 4   (6.0)
x //= 2  # x = x // 2  (3)
x %= 2   # x = x % 2   (1)
x **= 3  # x = x ** 3  (1)
// JavaScript
let x = 10;
x += 5;   // 15
x -= 3;   // 12
x *= 2;   // 24
x /= 4;   // 6
x %= 2;   // 0
x **= 3;  // 0
// Bitwise compound assignment
x = 5;
x &= 3;   // 1 (101 & 011 = 001)
x |= 2;   // 3 (001 | 010 = 011)
x ^= 1;   // 2 (011 ^ 001 = 010)
x <<= 1;  // 4 (010 << 1 = 100)
x >>= 1;  // 2 (100 >> 1 = 010)

Destructuring Assignment

// JavaScript - Array destructuring
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);  // 1, 2, 3
// Swapping variables
[a, b] = [b, a];
console.log(a, b);  // 2, 1
// Object destructuring
let { name, age } = { name: "Alice", age: 30 };
console.log(name, age);  // Alice, 30
# Python - Tuple unpacking
a, b, c = 1, 2, 3
print(a, b, c)  # 1, 2, 3
# Swapping
a, b = b, a
print(a, b)  # 2, 1

Comparison Operators

Comparison operators compare two values and return a Boolean (true/false).

Equality Operators

// JavaScript - careful with equality!
let x = 5;
let y = "5";
console.log(x == y);   // true (loose equality, type conversion)
console.log(x === y);  // false (strict equality, no type conversion)
console.log(x != y);   // false (loose inequality)
console.log(x !== y);  // true (strict inequality)
# Python
x = 5
y = "5"
print(x == y)   # False (no type coercion)
print(x != y)   # True

Relational Operators

// JavaScript
let a = 10;
let b = 20;
console.log(a > b);   // false
console.log(a >= b);  // false
console.log(a < b);   // true
console.log(a <= b);  // true

Object Comparison

// JavaScript - objects compared by reference
let obj1 = { name: "Alice" };
let obj2 = { name: "Alice" };
let obj3 = obj1;
console.log(obj1 == obj2);   // false (different references)
console.log(obj1 === obj2);  // false
console.log(obj1 == obj3);   // true (same reference)
// Deep comparison would require custom logic
function deepEqual(obj1, obj2) {
return JSON.stringify(obj1) === JSON.stringify(obj2);
}

Logical Operators

Logical operators combine Boolean values or expressions.

AND, OR, NOT

// JavaScript
let isLoggedIn = true;
let isAdmin = false;
// AND (&&) - both must be true
console.log(isLoggedIn && isAdmin);  // false
// OR (||) - at least one must be true
console.log(isLoggedIn || isAdmin);  // true
// NOT (!) - inverts the value
console.log(!isLoggedIn);  // false
console.log(!isAdmin);     // true
# Python
is_logged_in = True
is_admin = False
# AND
print(is_logged_in and is_admin)  # False
# OR
print(is_logged_in or is_admin)   # True
# NOT
print(not is_logged_in)  # False
print(not is_admin)      # True

Logical Operators with Non-Booleans

// JavaScript - short-circuit evaluation
console.log(0 && 5);      // 0 (falsy)
console.log(5 && 10);     // 10 (truthy)
console.log(0 || 5);      // 5 (truthy)
console.log(5 || 10);     // 5 (truthy)
// Common patterns
let name = userInput || "Guest";  // Default value
let isValid = condition && doSomething();  // Conditional execution
# Python
print(0 and 5)      # 0
print(5 and 10)     # 10
print(0 or 5)       # 5
print(5 or 10)      # 5
# Common patterns
name = user_input or "Guest"  # Default value

Nullish Coalescing Operator

// JavaScript - ?? operator (ES2020)
let value = null ?? "default";    // "default"
let value2 = 0 ?? "default";      // 0 (not null/undefined)
let value3 = undefined ?? "default"; // "default"
// vs OR operator
let orValue = 0 || "default";     // "default" (0 is falsy)

Bitwise Operators

Bitwise operators perform operations on the binary representations of numbers.

Bitwise Operators Table

OperatorNameExampleResult
&AND5 & 31 (101 & 011 = 001)
|OR5 | 37 (101 | 011 = 111)
^XOR5 ^ 36 (101 ^ 011 = 110)
~NOT~5-6 (inverts bits)
<<Left shift5 << 110 (1010)
>>Right shift5 >> 12 (10)
>>>Zero-fill right shift-5 >>> 12147483645 (JS only)

Bitwise AND, OR, XOR

// JavaScript
let a = 5;  // Binary: 0101
let b = 3;  // Binary: 0011
console.log(a & b);   // 1 (0001)
console.log(a | b);   // 7 (0111)
console.log(a ^ b);   // 6 (0110)

Bitwise NOT

// JavaScript
let x = 5;    // Binary: 0101
console.log(~x);  // -6 (11111111111111111111111111111010)
// For 32-bit signed integers
console.log(~x & 0xFFFFFFFF);  // 4294967290 (unsigned)

Bitwise Shifts

// JavaScript
let x = 5;  // 0101
console.log(x << 1);   // 10 (1010)  (multiply by 2)
console.log(x << 2);   // 20 (10100) (multiply by 4)
console.log(x >> 1);   // 2 (10)     (divide by 2)
console.log(x >> 2);   // 1 (1)      (divide by 4)
// Negative numbers
let y = -5;
console.log(y >> 1);   // -3 (arithmetic shift preserves sign)

Bitwise Flags Example

// Using bitwise operators for flags
const PERMISSIONS = {
READ:    1 << 0,  // 1 (001)
WRITE:   1 << 1,  // 2 (010)
DELETE:  1 << 2,  // 4 (100)
ADMIN:   1 << 3   // 8 (1000)
};
let userPermissions = PERMISSIONS.READ | PERMISSIONS.WRITE;  // 3 (011)
// Check permission
function hasPermission(permissions, permission) {
return (permissions & permission) === permission;
}
console.log(hasPermission(userPermissions, PERMISSIONS.READ));   // true
console.log(hasPermission(userPermissions, PERMISSIONS.DELETE)); // false
// Add permission
userPermissions |= PERMISSIONS.DELETE;  // Now has DELETE (7)
// Remove permission
userPermissions &= ~PERMISSIONS.WRITE;  // Remove WRITE (5)
// Toggle permission
userPermissions ^= PERMISSIONS.READ;    // Toggle READ

String Operators

Concatenation

// JavaScript
let firstName = "John";
let lastName = "Doe";
// + operator for concatenation
let fullName = firstName + " " + lastName;
console.log(fullName);  // "John Doe"
// Template literals (ES6)
let greeting = `Hello, ${firstName} ${lastName}!`;
console.log(greeting);  // "Hello, John Doe!"
# Python
first_name = "John"
last_name = "Doe"
# + operator
full_name = first_name + " " + last_name
print(full_name)  # "John Doe"
# f-strings (Python 3.6+)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)  # "Hello, John Doe!"
# format() method
greeting2 = "Hello, {} {}!".format(first_name, last_name)

String Comparison

# Python - lexicographic comparison
print("apple" < "banana")     # True
print("Apple" < "apple")      # True (ASCII comparison)
print("abc" == "abc")          # True
# Case-insensitive comparison
print("APPLE".lower() == "apple".lower())  # True
// JavaScript
console.log("apple" < "banana");     // true
console.log("Apple" < "apple");      // true
console.log("abc" === "abc");        // true
// Locale-aware comparison
console.log("apple".localeCompare("banana"));  // -1

Type Operators

typeof Operator

// JavaScript
console.log(typeof 42);           // "number"
console.log(typeof "Hello");      // "string"
console.log(typeof true);         // "boolean"
console.log(typeof undefined);    // "undefined"
console.log(typeof null);         // "object" (quirk)
console.log(typeof {});           // "object"
console.log(typeof []);           // "object"
console.log(typeof function(){}); // "function"
// Checking array type
console.log(Array.isArray([]));   // true
# Python
print(type(42))           # <class 'int'>
print(type("Hello"))      # <class 'str'>
print(type(True))         # <class 'bool'>
print(type(None))         # <class 'NoneType'>
print(type([]))           # <class 'list'>
print(type({}))           # <class 'dict'>
print(type(lambda x: x))  # <class 'function'>
# isinstance() - better for type checking
print(isinstance(42, int))          # True
print(isinstance([], list))         # True
print(isinstance("abc", str))       # True

instanceof Operator

// JavaScript
class Animal {}
class Dog extends Animal {}
let dog = new Dog();
console.log(dog instanceof Dog);      // true
console.log(dog instanceof Animal);   // true
console.log(dog instanceof Object);   // true
// Primitive types
console.log(42 instanceof Number);    // false (primitive)
console.log(new Number(42) instanceof Number);  // true

in Operator

// JavaScript
let person = { name: "Alice", age: 30 };
console.log("name" in person);    // true
console.log("salary" in person);  // false
console.log("toString" in person); // true (inherited)
// Arrays
let arr = [10, 20, 30];
console.log(0 in arr);     // true (index)
console.log(3 in arr);     // false
console.log("length" in arr); // true
# Python
person = {"name": "Alice", "age": 30}
print("name" in person)     # True
print("salary" in person)   # False
# Lists
arr = [10, 20, 30]
print(10 in arr)  # True (value, not index)

Ternary/Conditional Operator

The ternary operator is a shorthand for if-else statements.

Basic Ternary

// JavaScript
let age = 18;
let status = age >= 18 ? "Adult" : "Minor";
console.log(status);  // "Adult"
// Nested ternary
let grade = 85;
let letter = grade >= 90 ? "A" :
grade >= 80 ? "B" :
grade >= 70 ? "C" :
grade >= 60 ? "D" : "F";
console.log(letter);  // "B"
# Python
age = 18
status = "Adult" if age >= 18 else "Minor"
print(status)  # "Adult"
# Nested ternary (use sparingly)
grade = 85
letter = "A" if grade >= 90 else \
"B" if grade >= 80 else \
"C" if grade >= 70 else \
"D" if grade >= 60 else "F"
print(letter)  # "B"

Practical Usage

// Conditional function calls
let isLoggedIn = true;
isLoggedIn ? showDashboard() : showLogin();
// Conditional rendering (React)
return (
<div>
{isLoading ? <Spinner /> : <Content />}
</div>
);
// Default values
let name = inputName ? inputName : "Guest";
let name = inputName || "Guest";  // Alternative with OR

Operator Precedence

Operator precedence determines the order in which operations are evaluated.

Precedence Table (Highest to Lowest)

// JavaScript precedence
console.log(2 + 3 * 4);     // 14 (multiplication first)
console.log((2 + 3) * 4);   // 20 (parentheses first)
// Full precedence order (simplified):
// 1. () - Parentheses
// 2. ** - Exponentiation
// 3. * / % - Multiplication, Division, Remainder
// 4. + - - Addition, Subtraction
// 5. << >> >>> - Bitwise shifts
// 6. < <= > >= - Relational
// 7. == != === !== - Equality
// 8. & - Bitwise AND
// 9. ^ - Bitwise XOR
// 10. | - Bitwise OR
// 11. && - Logical AND
// 12. || - Logical OR
// 13. ?? - Nullish coalescing
// 14. ? : - Ternary
// 15. = += -= etc. - Assignment

Associativity

// Left-associative (most operators)
console.log(10 - 5 - 2);   // (10 - 5) - 2 = 3
// Right-associative (exponentiation, assignment)
console.log(2 ** 3 ** 2);  // 2 ** (3 ** 2) = 512
let a = b = c = 5;          // Right-associative

Operator Overloading

Operator overloading allows custom behavior for operators with user-defined types.

Python Operator Overloading

# Python - operator overloading with magic methods
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
print(v1 + v2)      # Vector(6, 8)
print(v1 - v2)      # Vector(-2, -2)
print(v1 * 3)       # Vector(6, 9)
print(v1 == v2)     # False

JavaScript Operator Overloading (No direct support)

// JavaScript - no operator overloading
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
add(other) {
return new Vector(this.x + other.x, this.y + other.y);
}
toString() {
return `Vector(${this.x}, ${this.y})`;
}
}
let v1 = new Vector(2, 3);
let v2 = new Vector(4, 5);
console.log(v1.add(v2).toString());  // Vector(6, 8)

Special Operators

Spread Operator

// JavaScript - spread operator (...)
// Arrays
let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5];  // [1, 2, 3, 4, 5]
let copy = [...arr1];          // Shallow copy
// Objects
let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1, c: 3 };  // { a: 1, b: 2, c: 3 }
// Function calls
let numbers = [1, 2, 3, 4, 5];
let max = Math.max(...numbers);  // 5
# Python - unpacking operator (* and **)
# Lists/tuples
arr1 = [1, 2, 3]
arr2 = [*arr1, 4, 5]  # [1, 2, 3, 4, 5]
copy = [*arr1]        # Shallow copy
# Dictionaries
dict1 = {"a": 1, "b": 2}
dict2 = {**dict1, "c": 3}  # {"a": 1, "b": 2, "c": 3}
# Function calls
numbers = [1, 2, 3, 4, 5]
print(*numbers)  # 1 2 3 4 5

Optional Chaining

// JavaScript - optional chaining (?.)
let user = {
profile: {
name: "Alice"
}
};
console.log(user?.profile?.name);      // "Alice"
console.log(user?.address?.city);      // undefined (no error)
console.log(user?.nonExistent?.value); // undefined
// With function calls
let obj = {
method: () => "result"
};
console.log(obj.method?.());  // "result"
console.log(obj.noMethod?.()); // undefined

Nullish Coalescing

// JavaScript - nullish coalescing (??)
let value = null ?? "default";     // "default"
let value2 = undefined ?? "default"; // "default"
let value3 = 0 ?? "default";       // 0
let value4 = "" ?? "default";      // ""
let value5 = false ?? "default";   // false
// Unlike OR (||) which treats falsy values as default
let orValue = 0 || "default";      // "default"

Pipeline Operator

// JavaScript (proposal) - pipeline operator (|>)
// Not yet widely supported
// const result = "Hello" |> toUpperCase |> split('') |> reverse |> join('');
// Current approach with chaining
const result = "Hello".toUpperCase().split('').reverse().join('');

Short-Circuit Evaluation

Logical operators use short-circuit evaluation to optimize performance and enable conditional execution.

AND (&&) Short-Circuit

// JavaScript - && stops at first falsy value
console.log(false && expensiveFunction());  // false (expensiveFunction not called)
// Common pattern: conditional execution
isLoggedIn && showDashboard();  // Only calls showDashboard if isLoggedIn is true
# Python
def expensive_function():
print("Called!")
return True
print(False and expensive_function())  # False (function not called)

OR (||) Short-Circuit

// JavaScript - || stops at first truthy value
console.log(true || expensiveFunction());   // true (function not called)
// Common pattern: default values
let name = userInput || "Guest";

Nullish Coalescing (??) Short-Circuit

// JavaScript - ?? stops at first non-null/undefined
let value = null ?? expensiveFunction();     // expensiveFunction called
let value2 = 0 ?? expensiveFunction();       // 0 (function not called)

Common Pitfalls

1. Floating Point Precision

// JavaScript
console.log(0.1 + 0.2);        // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false
// Solution: use tolerance
const EPSILON = 0.000001;
console.log(Math.abs((0.1 + 0.2) - 0.3) < EPSILON);  // true
# Python
print(0.1 + 0.2)  # 0.30000000000000004
# Solution
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2'))  # 0.3

2. Loose vs Strict Equality

// JavaScript
console.log(5 == "5");   // true (type coercion)
console.log(5 === "5");  // false (strict)
console.log(0 == false); // true
console.log(0 === false);// false
// Best practice: use === always

3. Assignment vs Comparison

// JavaScript - common mistake
if (x = 5) {  // Assignment, not comparison!
// Always executes (5 is truthy)
}
// Correct
if (x === 5) {  // Comparison
}
# Python - assignment not allowed in if
# if x = 5:  # SyntaxError!
if x == 5:  # Correct
pass

4. NaN Comparisons

// JavaScript
console.log(NaN === NaN);  // false
console.log(isNaN(NaN));   // true
// Number.isNaN is more reliable
console.log(Number.isNaN(NaN));     // true
console.log(Number.isNaN("abc"));   // false (string not converted)

5. Integer Division

// JavaScript - always floating point
console.log(5 / 2);   // 2.5
// For integer division
console.log(Math.floor(5 / 2));  // 2
console.log(5 >> 1);             // 2 (bitwise)
// Java - integer division truncates
int x = 5 / 2;  // 2
double y = 5.0 / 2;  // 2.5

Interview Questions

Q1: What's the difference between == and === in JavaScript?

// == compares values after type coercion
console.log(5 == "5");     // true
console.log(0 == false);   // true
console.log(null == undefined); // true
// === compares values without type coercion
console.log(5 === "5");    // false
console.log(0 === false);  // false
console.log(null === undefined); // false
// Best practice: always use === for predictable behavior

Q2: What will this output?

console.log(1 + "2" + "2");  // "122"
console.log(1 + +"2" + "2"); // "32"
console.log(1 + -"1" + "2"); // "02"
console.log(+"1" + "1" + "2"); // "112"
console.log("A" - "B" + "2"); // "NaN2"
console.log("A" - "B" + 2);   // NaN
// Explanation:
// +"2" converts "2" to number 2
// -"1" converts "1" to number -1
// "A" - "B" results in NaN

Q3: What's the output of this code?

let x = 5;
console.log(x++);  // 5
console.log(++x);  // 7
console.log(x);    // 7

Q4: How does short-circuit evaluation work?

// AND (&&) - returns first falsy or last truthy
console.log(0 && 5);      // 0
console.log(5 && 10);     // 10
console.log(5 && 10 && 0 && 20); // 0
// OR (||) - returns first truthy or last falsy
console.log(0 || 5);      // 5
console.log(5 || 10);     // 5
console.log(0 || "" || null); // null
// Practical use
let user = getUser() || defaultUser;  // Default value
isAdmin && showAdminPanel();          // Conditional execution

Q5: Explain the difference between & and && in JavaScript?

// & is bitwise AND (operates on binary representation)
console.log(5 & 3);    // 1 (0101 & 0011 = 0001)
// && is logical AND (operates on truthiness)
console.log(5 && 3);   // 3 (short-circuits, returns last truthy)
// For booleans
console.log(true & true);   // 1 (numeric)
console.log(true && true);  // true (boolean)

Q6: What will this Python code output?

x = 5
y = 3
print(x / y)        # 1.666...
print(x // y)       # 1
print(x % y)        # 2
print(x ** y)       # 125
print(x == y)       # False
print(x != y)       # True

Q7: Explain the difference between is and == in Python?

# == compares values
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)   # True (same values)
print(a is b)   # False (different objects)
# is compares identity (memory location)
c = a
print(a is c)   # True (same object)
# With small integers (caching)
x = 256
y = 256
print(x is y)   # True (cached)
x = 257
y = 257
print(x is y)   # False (not cached)

Conclusion

Operators are fundamental building blocks of programming that allow us to manipulate data, make decisions, and control program flow.

Key Takeaways

CategoryOperatorsUse Case
Arithmetic+, -, *, /, %, **Mathematical calculations
Assignment=, +=, -=, *=, /=Variable assignment
Comparison==, ===, !=, !==, <, >, <=, >=Value comparison
Logical&&, ||, !Boolean logic
Bitwise&, |, ^, ~, <<, >>Bit manipulation
Ternarycondition ? a : bConditional expressions

Best Practices

  1. Use strict equality (=== in JS) to avoid type coercion surprises
  2. Understand short-circuit evaluation for conditional execution
  3. Be aware of floating point precision issues
  4. Use parentheses to make precedence explicit
  5. Avoid complex expressions - break them down for readability
  6. Consider operator overload in languages that support it
  7. Use bitwise operators carefully (mostly for flags and low-level operations)

Quick Reference

// Common operator patterns
// Default values
let name = input || "Guest";
// Conditional execution
isValid && doSomething();
// Increment/Decrement
let i = 0;
i++;  // post-increment
++i;  // pre-increment
// Bitwise flags
const READ = 1 << 0;
const WRITE = 1 << 1;
let permissions = READ | WRITE;
// Ternary
let status = age >= 18 ? "adult" : "minor";

Understanding operators is essential for writing efficient and expressive code. Master these concepts to become a more effective programmer!

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper