Check Odious Number in Java
Problem
An odious number is a non-negative integer whose binary representation contains an odd number of 1 bits — the mirror image of an evil number.
Given a number, determine whether it is an odious number.
Java Program
public class OdiousNumberCheck {
public static void main(String[] args) {
int num = 7;
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 odious number: " + (bitCount % 2 != 0));
}
}Output
Core Logic
Checking the lowest bit and shifting right, repeated until nothing is left, counts every 1 bit — the exact same scan used to check for evil numbers, with the opposite final parity check.
- 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 oddness with% 2 != 0.
7 (binary 111), all three bits are 1, giving a bitCount of 3 — an odd count, so 7 is reported as odious.Key Point: Every non-negative integer is either evil or odious — never both, and never neither — since its bit count is always either even or odd.
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 OdiousNumberBuiltin {
public static void main(String[] args) {
int num = 7;
// bitCount() returns the number of 1 bits directly
boolean isOdious = Integer.bitCount(num) % 2 != 0;
System.out.println(num + " is an odious number: " + isOdious);
}
}
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 oddness with
% 2 != 0, the same final step as the manual version.
Integer.bitCount(7) returns 3, which is odd, so 7 is reported as odious.Key Point: Swapping % 2 == 0 for % 2 != 0 is the only change from the evil-number check — everything else about the bit-counting logic is identical.
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 OdiousNumberStream {
public static void main(String[] args) {
int num = 7;
// Counts the '1' characters in the binary string representation
long bitCount = Long.toBinaryString(num).chars().filter(c -> c == '1').count();
boolean isOdious = bitCount % 2 != 0;
System.out.println(num + " is an odious number: " + isOdious);
}
}
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 oddness the same way as the other approaches.
Long.toBinaryString(7) gives "111"; filtering and counting the '1' characters gives 3, an odd count, so 7 is reported as odious.Key Point: Swapping % 2 == 0 for % 2 != 0 is again the only change from the evil-number version of this same stream pipeline.
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.