while 循环比它应该的更多或更少地迭代自己

While loop iterates itself more or less than it should

Austin Hastings 和 Michael Burr 的回答解决了我的问题,这个循环总是正确的,正如我刚刚意识到的那样,它像 Austin Hastings 那样解决了。无法标记为答案,因为它是评论。感谢您的帮助!

我在 C 中有一个任务,它只打印 128 到 255 之间的特定类型的数字(所以 8 位二进制表示),我应该在不使用任何算术运算符的情况下完成它。条件是:

  1. 数字的二进制表示必须具有相同数量的 0 和 1。
  2. 从左到右读取时,数字的二进制表示在任何时候都不能有比 1 多的 0。例如156(1001 1100)不满足第二个条件,因为第3位有两个0,只有一个1,而210(1101 0010)满足这些条件。

我正在使用功能实现,并为这两个条件使用了一个函数,那部分代码是:

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;
}

我经常有错误的输出,所以放置一些不影响代码的控制机制来跟踪问题。它们是:

我的问题是,如果我尝试让 while 循环工作直到最后一次使用进位且进位 = 0,它会给出 210 的输出,它应该可以工作,因为它循环了 8 次并且在 CARRY = -1 时它应该从循环就像:

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

所以它比它应该循环的次数多 1 并且它使 count 多 1 0 所以它失败了。但是我在 while 循环中将进位限制增加到 1 以查看会发生什么,它给出:

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

所以它通过了第三个条件,但比它应该的 0 少了一个,所以在第二个条件下失败了。

这似乎是一个复杂且过于具体的问题,但感谢您的任何提示。

我不确定你的 binaryAdditionbinarySubtraction 函数 - 你是否需要使用它们,或者只是为了满足不使用算术运算的条件而使用它们。

对于这个简单的例子,值得指出的是,您可以 "count" 使用整数中的位最多可以达到 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;
}