0

Anwers of Austin Hastings and Michael Burr has solved my problem, this loop is always true as I just realised and it's solved when did it like Austin Hastings did. Cannot mark as answer since it is a comment. Thanks for your help!

I have an assignment in C which is to print only specific kinds of numbers between an 128 and 255 (so 8 digit binary representations) and I should do it without using any arithmetic operators. The conditions are:

  1. Number's binary representation has to have same number of 0's and 1's.
  2. Number's binary representation cannot have more 0's than 1's at any moment when reading from left-to-right. For example, 156 (1001 1100) does not meet the 2nd condition because there are two 0's and only one 1 at the 3rd digit, while 210 (1101 0010) satisfies these conditions.

I am using functional implementation and used a single function for these two conditions and that part of code is:

int checkOneToZero(unsigned int num) {
    unsigned int carry = 7, 
        counterOne = 0, 
        counterZero = 0, 
        ct = 0;

    while ((carry > 0) || (carry == 0)) {
        if ((num >> carry) & 1) {
            counterOne = binaryAddition(counterOne, 1);
            ct ++;
            printf(" %d ", ct); 
        }
        else {
            counterZero = binaryAddition(counterZero, 1);
            ct ++;
            printf(" %d ", ct); 
        }

        carry = binarySubtraction(carry, 1);
        printf(" CARRY %d \n", carry);

        if (counterZero > counterOne) {
            printf(" breakCounterZero %d breakCounterOne %d ", counterZero, counterOne);
            return 0;
        }
    }

    printf("successCounterZero = %d successCounterOne = %d", counterZero, counterOne);

    if (counterZero == counterOne)
        return 1;

    return 0;
}

I had wrong output constantly so put some control mechanisms which do not effect the code to track the problem. These are:

  • ct : Counts how many times it has enter into if or else in while loop.

  • printf(" CARRY %d \n", carry) : shows carry's value after it has been decreased one.

  • printf(" breakCounterZero = &d breakCounterOne = %d ") : shows 0 and 1 counts if it has stuck at "if (counterZero > counterOne)" which checks 0 count cannot be higher than 1 count at the end of each while loop.

  • printf("successCounterZero = %d successCounterOne = %d") : shows if it has passed the while loop.

My problem is if I try to let while loop work until carry is used last with carry = 0, it gives output of 210, which should work as it loops 8 times and at CARRY = -1 it should break from the loop while it is like:

1  CARRY 6
2  CARRY 5
3  CARRY 4
4  CARRY 3
5  CARRY 2
6  CARRY 1
7  CARRY 0
8  CARRY -1
9  CARRY -2
breakCounterZero 5 breakCounterOne 4

so it loops 1 more time than it should and it makes count one more 0 so it fails. But wen I increased limit of carry to 1 in while loop to see what happens, it gives:

1  CARRY 6
2  CARRY 5
3  CARRY 4
4  CARRY 3
5  CARRY 2
6  CARRY 1
7  CARRY 0
successCounterZero = 3 successCounterOne = 4

so it passes the 3rd condition but one less 0 than it should so fails at 2nd condition.

This seems to be a complicated and a too-specific question, but thanks for any hints.

4

1 回答 1

0

我不确定您的binaryAdditionandbinarySubtraction函数 - 您是否需要使用它们,或者只是使用它们来满足不使用算术运算的条件。

对于这个简单的情况,值得指出的是,您可以使用整数中的位“数”到 31。当然足以处理 8 个可能的值:

int checkOneToZero(unsigned num) 
{
    unsigned count_0s = 0;
    unsigned count_1s = 0;

    // Using a 'for' loop here because I know the start, stop, and update.
    for (unsigned check_bit = 1 << 7; check_bit; check_bit >>= 1) {
        if (num & check_bit) {
            /* ++count_1s; */
            count_1s |= (count_1s << 1) | 1;
        }
        else {
            /* ++count_0s; */
            count_0s |= (count_0s << 1) | 1;

            if (count_0s > count_1s) return 0;
        }
    }

    return count_0s == count_1s;
}
于 2016-03-24T23:48:10.923 回答