Check Evil Number in Java
Problem
An evil number is a non-negative integer whose binary representation contains an even number of 1 bits.
Given a number, determine whether it is an evil number.
Java Program
public class EvilNumberCheck {
public static void main(String[] args) {
int num = 3;
int original = num;
int bitCount = 0;
while (num > 0) {
if ((num & 1) == 1) bitCount++; // lowest bit is set
num >>>= 1; // shift right, discarding the bit just checked
}
System.out.println(original + " is an evil number: " + (bitCount % 2 == 0));
}
}Output
Core Logic
Checking the lowest bit and shifting right, repeated until nothing is left, counts every 1 bit in the number's binary form one at a time.
- 1
num & 1checks whether the current lowest bit is1, incrementingbitCountwhen it is. - 2
num >>>= 1shifts every bit one position to the right, discarding the bit just checked. - 3The loop repeats until
numbecomes0, meaning every bit has been examined. - 4The final
bitCountis checked for evenness with% 2 == 0.
3 (binary 11), both bits are 1, giving a bitCount of 2 — an even count, so 3 is reported as evil.Key Point: >>>, the unsigned right shift, is used instead of >> so the sign bit never gets replicated into the high bits — not a concern for small positive numbers here, but the safer default for bit-counting code.
Why: The loop runs once per bit in the number's binary representation, so the work scales with the number's bit length, not its value.
Key Concepts
Approach 2: Using Integer.bitCount()
public class EvilNumberBuiltin {
public static void main(String[] args) {
int num = 3;
// bitCount() returns the number of 1 bits directly
boolean isEvil = Integer.bitCount(num) % 2 == 0;
System.out.println(num + " is an evil number: " + isEvil);
}
}
Output
Core Logic
In real code, there's no reason to count bits manually — Integer.bitCount() already does exactly that in one call.
- 1
Integer.bitCount(num)returns the number of1bits in the number's binary representation directly. - 2That count is checked for evenness with
% 2 == 0, the same final step as the manual version.
Integer.bitCount(3) returns 2, which is even, so 3 is reported as evil.Key Point: This is the version to actually use — the manual bit-by-bit loop exists only to show what bitCount() is conceptually doing under the hood.
Why: Integer.bitCount() is a JDK intrinsic that typically compiles down to a single hardware instruction, rather than looping bit by bit.
Key Concepts
Approach 3: Java 8
public class EvilNumberStream {
public static void main(String[] args) {
int num = 3;
// Counts the '1' characters in the binary string representation
long bitCount = Long.toBinaryString(num).chars().filter(c -> c == '1').count();
boolean isEvil = bitCount % 2 == 0;
System.out.println(num + " is an evil number: " + isEvil);
}
}
Output
Core Logic
Turning the number into its binary string and counting the '1' characters with a stream is a more declarative way to ask the same question.
- 1
Long.toBinaryString(num)converts the number into aStringof its binary digits, with no leading zeros. - 2
.chars()returns anIntStreamof that string's character codes. - 3
.filter(c -> c == '1')keeps only the codes representing a'1'character. - 4
.count()reduces the filtered stream down to the total number of set bits, checked for evenness the same way as the other approaches.
Long.toBinaryString(3) gives "11"; filtering and counting the '1' characters gives 2, an even count, so 3 is reported as evil.Key Point: This does more work than Integer.bitCount() — building a whole string just to count characters in it — but reads closer to the plain-English definition of the check.
Why: Building the binary string costs space proportional to the number's bit length, unlike the two loop-based approaches, which only ever hold a running count.