Bit Count confusion (task 81)

Back to Problem Solutions forum

bpzzt_br     2014-11-06 19:14:33

Hello! I'm a bit confused about this problem, what is the preferred method to change a negative number into binary? I searched online and found three methods, and judging by the example it looks like the problem wants me to use 2s complement. Is that correct?

Rodion (admin)     2014-11-06 20:31:18
User avatar

Hi, thanks for your question!

You are right this problem supposes that values are stored as 32-bit integers. If I remember correctly, Python is somewhat vague about this (it pretends that integers are of infinite length, yeah?)

Nevertheless you can either manually represent them as 2s complement binary, or even avoid this by and-ing the value with 1, then with 2, then with 4 and so on for 32 times, counting how many times the result was non-zero.

I think I should improve the problem statement since many people use Python - thank you for this hint!

bpzzt_br     2014-11-07 01:52:30

Glad to have been able to help (even if by accident)!

I'm having trouble with the solution when it comes to negative numbers. I think my code is correct, though. Maybe you can give me some tips:

def bit_list_generator():
    bit_num = 1
    bit_list = [1]

    for i in range(1,32):
        bit_num *= 2
        bit_list.append(bit_num)

    bit_list.reverse()
    return bit_list

def bit_converter(number):
    bit_list = bit_list_generator()
    answer = []

    if number >= 0:
        for i in bit_list:
            if number >= i:
                answer.append(1)
                number = number % i
            else:
                answer.append(0)
    elif number < 0:
        number = abs(number)
        for i in bit_list:
            if number >= i:
                answer.append(1)
                number = number % i
            else:
                answer.append(0)

        inverted = []
        for i in answer:
            if i == 1:
                inverted.append(0)
            elif i == 0:
                inverted.append(1)
        del inverted[-1]

        inverted.append(1)

        answer = inverted

    return answer
bpzzt_br     2014-11-07 02:07:48

First I have a function that creates the list with the positional values I'll need to do the conversion in the other function.

The other function is where the conversion happens.

If the integer is positive it does the conversion by dividing the number by each value in the list (adding 1 to another list if there was a division, zero if there was no division) and continuing through the list with the remainder.

If the number is negative:

  1. The number is first converted into positive;
  2. It is converted into binary normally, same as above;
  3. Each digit is then "inverted" and put into another list (if it's 0 it becomes 1 and vice-versa);
  4. The last digit is deleted;
  5. The digit "1" is added to the list at the last position

This follows the explanation I read on an article online ehow article, but I'm being told my answer is incorrect!

Rodion (admin)     2014-11-07 06:38:02
User avatar

Hi!

I ran your algorithm for few values:

print(bit_converter(5))
print(bit_converter(-1))
print(bit_converter(-2))

It gives correct result (all ones) for -1, but for -2 it gives ...1111101 which is not right. It should be ...1111110 instead. You can check this by adding 1 (because -2 + 1 = -1).

The five steps you mentioned look almost correct except the 4 and 5 steps. There should be simple addition of 1 instead. Shortly speaking:

To convert value to or from negative (this works both ways):

  • invert all of its bits;
  • add 1 to the result (performing as many carries as necessary except for most significant bit).

E.g., for 8-bit values 1, 2, 0, 5, -1, -2 negation process looks like:

from      invert    add-1
00000001  11111110  11111111
00000010  11111101  11111110
00000000  11111111  00000000
00000101  11111010  11111011
11111111  00000000  00000001
11111110  00000001  00000010

P.S. I probably poorly expressed myself earlier - it is not necessary to build 2-s complement representation manually since the values already exist in its form in computer memory. Bitwise operations could be used to extract bits one by one. However, anyway your approach is methodically correct (and probably leads to better understanding of binary system), it only may need small fix we are discussing :)

bpzzt_br     2014-11-07 14:25:06

Interesting! So it requires a bit more processing than I thought. I'm not sure yet how to add 1, that's why I thought it would be the same to simply attach the one at the end. I'll work on the necessary modifications. Thanks!

nicolas_patrois     2014-11-07 14:39:29
User avatar

This task does not need a lot of processing (my Python code is 21 lines long and it can be shortened), it depends on how you see and process the data.

Rodion (admin)     2014-11-07 14:56:57
User avatar

I've added 5-line python snippet for counting bits to the "notes" which are shown when task is solved - hope these are correct though I'm not strong in Python.

bpzzt_br     2014-11-09 15:14:53

I added a "bit adder" function if the number is negative. May not be the best possible solution but it worked! I'm still very much a beginner to programming, and don't have a lot of skill in mathematics, so I still tend to do things the most difficult way sometimes. I've noticed many of my solutions are around 50 or more lines long while other people solve the problems with closer to 5! ;-)

def one_bit_adder(binary_number):
    binary_number = list(reversed(binary_number))
    for i in range(0,len(binary_number)):
        if binary_number[i] == 0:
            binary_number[i] = 1
            break
        elif binary_number[i] == 1:
            binary_number[i] = 0

    binary_number = list(reversed(binary_number))
    return binary_number
Rodion (admin)     2014-11-09 15:32:19
User avatar

> I've noticed many of my solutions are around 50 or more lines long while other people solve the problems with closer to 5! ;-)

I glad you've done this problem :)

As about the length of code - I've noticed that people sometimes return to their old code rewriting and resubmitting them - so often what you see as tiny and tidy solution is the result of cleanup and refactoring!

bpzzt_br     2014-11-09 16:05:04

Ok, that's encouraging, thanks!

omar_batistuta     2020-01-12 19:13:07

Rodion please if you can help a little bit(Somebody else can help too). I am stuck with this task. I am complete begginer in programming. My soultions are huge, lot of lines of code, but things works(so far). Until this task lol. Problem is with negative numbers. When i use bigger negative numbers the results are not precise. Code snippet for negative numbers:

if(a < 0) { int b = Math.abs(a); ArrayList<Integer> lista1 = new ArrayList<>(); ArrayList<Integer> lista2 = new ArrayList<>(); ArrayList<Integer> lista3 = new ArrayList<>(); int raz1 = 0; while(true) { raz1 = b/2; int ost1 = b % 2; lista1.add(ost1); b = raz1; if(raz1 == 0) { break; } } int vl = lista1.size(); int praznaMesta = 32 -vl; for(int i = 0; i < praznaMesta;i++) { lista2.add(0); } lista2.addAll(lista1); for(int i = 0; i < lista2.size();i++) { if(lista2.get(i) == 0) { lista3.add(1); } else { lista3.add(0); } } String firstNumber = lista3.stream().map(Object::toString).collect(Collectors.joining("")); // nacin da se lista integera pretvori u String

        String secondNumber = "00000000000000000000000000000001";

// long number0 = Long.parseLong(prviBroj, 2); // long number1 = Long.parseLong(drugiBroj, 2); // // long sum = number0 + number1; // String st = Long.toBinaryString(sum);

        String st = addBinary(firstNumber, secondNumber);

        char[] d = st.toCharArray();
        for(int i = 0; i < d.length;i++) {
            if(d[i] == '1') {
                count++;
            }
        }
    }

    ps. My moto is : Keep it simple :)
Rodion (admin)     2020-01-12 19:36:07
User avatar

Hi Friend :)

Well, I had a look at your code... Well, that's hard to "help a bit". The task is not really complicated (at least I think you've solved some more tricky ones)...

Your main problem is that you do things over-complicated. Try to stop and think "what am I doing and whether all this stuff is necessary".

For example:

int[] z = new int[m.length];
for(int i = 0; i < n;i++) {
    z[i] = Integer.parseInt(m[i]);
    System.out.print(calculate(z[i]) + " ");
}    

You obviously don't need array z - you only use every cell as temporary variable inside loop

for(int i = 0; i < n;i++) {
    int z = Integer.parseInt(m[i]);
    System.out.print(calculate(z) + " ");
}    

Not specifically to this task:

  1. Remove all the code inside your solution function and all dependent, you don't need this, no arraylists, nor something alike.
  2. Read a bit about bit operations in java. You can work with % and / (with some caution for negative numbers) but it would be easier to use dedicated operators & and >> or >>>.
  3. The whole calculate function should contain single loop and be no more than 10 lines (perhaps 5). Try to fit it in this size. If you do more - probably you do something wrong :)

Hope this helps! Cheer up, you know how to code - just now let's try to learn how to code better :)

omar_batistuta     2020-01-12 20:13:25

Wow!OMG. Your answer is so fast. I stil cant belive how fast it is. You must be using artifical inteligence or something, seriously ;). I type this message just to check if this forum is alive. I didnt even expect the answer, cause i didnt sent you the code. I try to edit my code, just not to look unserious(bdw i do it prety bad). However when i edit it, complete answer already came. Thanks a lot Rodion( or AI that you instal here lol). Your tips are very useful to me.

Rodion (admin)     2020-01-12 20:58:45
User avatar

He-he :) Honestly it was luck / coincidence. Regretfully sometimes I don't visit the site for days (even weeks). The idea of the forums here was that people can help each other (this is quite important not only to write the code but to read other's code, right)...

But now I just came from ice skating and looked into as I remembered there is unanswered question (about certificates) - can't yet compose my mind about this. And also I'm thinking about minor improvements to login system etc...

cause i didnt sent you the code

But for every user profile here is the page with failed problems :)

like this one

and admin account of course has rights to peek into the code... but probably we need to make it more obvious for people who create posts at forum somehow... I'll try to think of this too :)

or AI that you instal here lol

We had a joke long ago about one of former Soviet presidents, like he is speaking on radio:

"There are rumors, that instead of me here is grammophone record playing! Surely it's not so! Crr-click ...not so! Crr-click ...not so! ..."

So everything is possible :)

omar_batistuta     2020-01-12 22:12:26

Ha-ha-ha! Good joke! I am guessing it was Breznev.

So everything is possible :)

Here on Balcans we have phrase: "If you confess we will forgive you half." ;)

also I'm thinking about minor improvements

You can change everything, except charging ;). Jokeing a little bit. Now seriously, your site is excelent for begginers. It helps me a lot, specially good thing is that i can see other people code(people who knows how to solve task in couple lines of code), when i solve the task. That is extremly important for me. Once again, thanks for everything.

Please login and solve 5 problems to be able to post at forum