+ 4
[Solved] Counting 1's of a number in binary
I'm trying to count the 1's of a number in binary code. I use Integer.toBinaryString(num) to get the binary representation and store it in a String variable. Then I loop each characher with toCharArray() method. But if I check character == 1, it always return false. Even with Integer.valueOf(characher), it returns false too. If I change the "1" to 49 (ascii code for 1), it returns true. Why I need 49 in this case. How to make character == 1 returns true? https://code.sololearn.com/cY9VgBY0zB38/?ref=app
12 Answers
+ 5
Crazy shortcut:
int ones = Integer.bitCount(num);
The Stream method:
String bits = Integer.toBinaryString(num);
long count = bits.chars().filter(c -> c == '1').count();
+ 4
Instead of checking if a char is equal to '1', you can also sum up all values:
count += Character.getNumericValue(i);
Character.getNumericValue() converts a char to its integer (not ascii) value -> '1' = 1, '0' = 0, '9' = 9 and so on.
+ 4
Wong Hei Ming
Jays Solution works. Maybe you have an error in your code.
49 is the ascii value of '1'.
valueOf() returns the ascii value
parsing to int gives you also the ascii value
that's why Character has getNumericValue()
Tibor Santa
I'm sure there is also a solution using Streams. But I'm not familiar enough with streams. Maybe you have time to show a much easier solution. :)
+ 4
On topic:
You can also roll your own bit counter with some simple bitwise operations.
int ones = 0;
while (n > 0) {
ones += n & 1;
n >>= 1;
}
https://code.sololearn.com/cy78POXHveec/?ref=app
Side topic:
Programming languages can be categorized differently.
- interpreted or compiled
- static or dynamic typing
- weak or strong types
- memory management: manual, garbage collector, or other (like borrow checker in Rust)
- by dominant paradigm: OOP, functional, imperative
- mainstream, niche, experimental, esoteric
Python has its own place where it shines, particularly in data analysis and AI research, also in devops scripting, and even backend web apps. It is not really suited for building large OOP systems.
+ 4
Wong Hei Ming here is a technique that counts bits directly and minimizes loop iterations to exactly the number of 1 bits. (Brian Kernighan, the inventor of the C language, called it his favorite bit counter):
int num = 99;
int count = 0;
for (int n = num; n!=0; ++count)
n &= n - 1;
System.out.println(count);
The technique clears the rightmost bit that is set to 1 and repeats. It counts how many times it finds a 1 bit to clear.
To understand how it works, consider what happens in binary when you subtract 1. The rightmost 1 bit becomes 0, and all the 0 bits to the right of that bit become 1. Using that result as a mask with bitwise & automatically clears the next 1 bit.
Example:
1100011 - 1 = 110010;
1100011 & 1100010 = 1100010
1100010 - 1 = 1100001;
1100010 & 1100001 = 1100000
1100000 - 1 = 1011111;
1100000 & 1011111 = 1000000
1000000 - 1 = 0111111;
1000000 & 0111111 = 0000000
There were 4 iterations until the number became 0, so there were four 1 bits cleared.
+ 2
Wong Hei Ming
Yes, Java is a bit more fussy than Python ;)
' ' is only for chars.
To be honest, I can't really explain why valueOf() only spits out ascii values. I think that was a Java decision.
As I said, the ascii value of '1' (the char 1) is 49. Accordingly, Integer.valueOf('1') == 49 returns true.
Integer.valueOf('A') gives you 65.
+ 2
Wong Hei Ming the "cache" is related to how the Java Virtual Machine is internally handling the Integer objects in memory, basically to gain some performance improvement and save some memory by only creating identical objects once, and reusing them.
This is important because there is a difference how unboxed primitive types (int, long, ..) and boxed reference types (Integer, Long) are handled by Java internally. The main impact is about how you can compare values. If it's primitive types you can safely use the == operator but for objects you should always rely on the equals method.
+ 2
I think I'm going to understand why people say python developer writes bad code.
To my understanding there are high level language and low level language (let's put assembly language aside).
Python is a high level language and simplifies lots of things under the hood. It doesn't require declaring a variable with a specific datatype. Python assign memory base on how variable is declared behind the scenes, and allow changing a variable datatype on the fly.
While people come from C or C++ view it is a bad practice because python developer leave python do the memory management work, saying (implying) "they don't know how computer works".
And Java is like sitting in the middle. It has lots of high level method yet influenced by C family. In order to offload memory management work from developer there is an Integer and int, Boolean and boolean and others, making a wrapper-primitive relationship, and leaving the hard work to wrapper.
I think I have to look for what are the parameters and return types (wrapper or primitive) and decide which method is better in given scenario.
+ 1
Denise Roßberg
Strange, it works if it is '1', but not "1".
I was thinking like in python and forgot String, char and Character are different.
But I'm still wonder why Integer.valueOf(i) == 49 still return true.
I think i is evaluated to int 1.
Tibor Santa did show me Streams in other posts yet I haven't master it. That's why I chose the old approach.
0
It doesn't work as expected and returns an error.
However you do inspire me to a working solution.
String.valueOf(i).equals("1")
But question remains, why i == 49 returns true?
0
Denise Roßberg
Whoa, didn't know Java treat ' and " differently. It is not mentioned in the course or any material I read (maybe I haven't reach that part?)
I just tried
int n = 1;
System.out.print(Integer.valueOf(n)) returns 1
If I changed
char n = '1', it returns 49
Looking at javadoc about Integer.valueOf(), it says "This method will always cache values in range -128 to 127, inclusive, and may cache other values outside of this range."
Not very helpful.
A quick search there is no negative ascii values, while range -128 to 127 inclusive is like talking about ascii.
Yet "may cache other values outside of this range" is too...... confusing.