Java Operators & Bitwise Tricks
Arithmetic, increment/decrement, bitwise operations, masking, type casting in Java

Arithmetic Operators and Expressions
Java gives you a small but powerful set of arithmetic operators. These work pretty much the way you’d expect:
+→ Addition-→ Subtraction/→ Division*→ Multiplication%→ Modulus (returns the remainder after division)
You can use these operators on all numeric data types (byte, short, int, long, float, double, char), but not on boolean(Java refuses to treat true and false like numbers).
Operator Precedence (Highest → Lowest)
When you combine multiple operators in one expression, Java follows a fixed precedence order:
| Precedence | Operators | Meaning |
| 1 | * / % | Multiplication, Division, Modulus |
| 2 | + - | Addition, Subtraction |
So in an expression like:
int x = 10 + 6 * 2;
Java always evaluates the * first, then applies the +, giving you 22.
If you want to override the default order, parentheses still rule the world.
Java’s Type Promotion Rules (Why Your byte Suddenly Becomes an int)
One thing Java loves to do (usually without asking) is promote smaller data types during arithmetic. So even if you start with tiny types like byte or short, the moment you add or subtract them, Java lifts them into bigger types behind the scenes. It’s part of what Java calls numeric promotion.
byte,short, andcharall get promoted to int when used in an expressionbyte + short → intchar + short → intchar + int → int
If either operand is long, the whole expression becomes
longshort + long → long
If either side is a float, Java goes with
floatint + float → floatlong + float → float
And if a double enters the chat, everything becomes
doublefloat + double → doublelong + double → double
The idea is basically: Java always promotes to the “safer” type so nothing important gets lost.
Increment and Decrement Operators
Java gives us four operators to increase or decrease a value by 1. The only thing is when the increment/decrement happens.
Post-increment (
i++) → use the value first, then increase itPost-decrement (
i--) → use the value first, then decrease itPre-increment (
++i) → increase first, then use the valuePre-decrement (
--i) → decrease first, then use the value
Quick examples:
int x = 5;
System.out.println(x++); // prints 5, x becomes 6
System.out.println(++x); // x becomes 7, prints 7
int y = 10;
System.out.println(y--); // prints 10, y becomes 9
System.out.println(--y); // y becomes 8, prints 8
Bitwise Operators in Java — AND, OR, XOR, NOT, Shifts
Bitwise operators work directly on the binary representation of numbers. They’re super fast and great for low-level tasks like masks, flags, and performance-critical logic.
Main Bitwise Operators
| Operator | Symbol | Meaning | |
| AND | & | Sets a bit to 1 only if both bits are 1 | |
| OR | ` | ` | Sets a bit to 1 if either bit is 1 |
| XOR | ^ | Sets a bit to 1 if the bits are different | |
| NOT | ~ | Flips every bit | |
| Left Shift | << | Shifts bits left (multiply by 2ⁿ) | |
| Right Shift | >> | Arithmetic right shift (keeps sign bit) | |
| Unsigned Right Shift | >>> | Logical right shift (fills with 0) |
Truth Tables
AND (&)
| A | B | A & B |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
OR (|)
| A | B | **A | B** |
| 0 | 0 | 0 | |
| 0 | 1 | 1 | |
| 1 | 0 | 1 | |
| 1 | 1 | 1 |
XOR (^)
| A | B | A ^ B |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Bitwise Examples
int x = 10, y = 6, z;
Binary:
x = 10 → 00001010y = 6 → 00000110
AND
00001010
& 00000110
-----------
00000010 → 2
OR
00001010
| 00000110
-----------
00001110 → 14
XOR
00001010
^ 00000110
-----------
00001100 → 12
Shift Operators
int x = 10; // 00001010
int z;
Left Shift (<<)
x = 00001010
x << 1 = 00010100 → 20
General rule:x << k → x * 2^k
Right Shift (>>) (keeps the sign bit)
x = 00001010
x >> 1 = 00000101 → 5
General rule:x >> k → x / 2^k
How Negative Numbers Are Stored (Two’s Complement)
Let’s store -10:
Start with
+10
00001010Flip all bits (1’s complement)
11110101Add 1 (2’s complement)
11110110→ this represents-10in binary
Since the first bit is 1, the number is negative.
Right Shift With Negative Numbers
x = -10 = 11110110
x >> 1 = 11111011 // sign bit stays 1
x >>> 1 = 01111011 // fills with 0 → 123
>>> always shifts in zero, even for negative numbers.
Bitwise NOT (~)
x = 00001010 // 10
~x= 11110101 // -11
The rule is:~x = -(x + 1)
So:
~10 = -11
Bit Masking and Merging
Bit masking lets you check, set, or clear specific bits in an integer using bitwise operators. Think of it as controlling individual switches in a row of lights — you can flip only the ones you care about.
- Masking (checking a bit):
int flags = 0b1010; // 4 bits: 1010
int mask = 0b0010; // check 2nd bit
boolean isSet = (flags & mask) != 0; // true, 2nd bit is 1
- Merging (setting a bit):
int flags = 0b1000;
int mask = 0b0010;
flags = flags | mask; // set the 2nd bit
// flags = 1010
With just & and |, you can read and write bits efficiently, which is crucial in low-level programming, graphics, and flags handling.
Question: How to store 2 numbers in 1 byte?
A single byte is 8 bits, so if both numbers are small enough (≤ 4 bits each, i.e., 0–15), you can pack them together using bitwise operations.
Step 1: Define the numbers
byte a = 9; // 4 bits max: 1001
byte b = 6; // 4 bits max: 0110
Step 2: Pack them into 1 byte
byte packed = (byte) ((a << 4) | b);
a << 4→ moveato the higher 4 bits| b→ mergebinto the lower 4 bits
a = 1001 → 10010000
b = 0110 → 00000110
packed = 10010110 → 150 (decimal)
Step 3: Unpack the numbers
byte a2 = (byte) ((packed >> 4) & 0x0F); // high 4 bits
byte b2 = (byte) (packed & 0x0F); // low 4 bits
System.out.println(a2 + " " + b2); // 9 6
>> 4shifts high bits to low position& 0x0Fmasks out unwanted bits
This way, you store two 4-bit numbers in a single byte and retrieve them later.
Widening and Narrowing (Type Casting)
Widening / Upcasting
Converts smaller type → bigger type automatically.
Safe, no data loss.
byte b = 10;
int i = b; // byte → int (widening)
Narrowing / Downcasting
Converts bigger type → smaller type.
Must be explicit; can lose data.
int i = 130;
byte b = (byte) i; // narrowing, b = -126
Question: How to swap two numbers without a Temp variable?
Bitwise XOR lets you swap numbers:
int a = 5, b = 9;
a = a ^ b; // Step 1
b = a ^ b; // Step 2
a = a ^ b; // Step 3
System.out.println(a + " " + b); // 9 5
No extra memory needed.



