0

所以有人告诉我,这是可以做到的,按位运算和掩码可能非常有用,但我必须在它们的工作方式上遗漏一些东西。

我试图计算一个数字,比如 x,是否是 y 的倍数。如果 x 是 y 的倍数,那么我想增加 x 以达到大于 x 的最接近的 y 倍数(以便所有 x 都适合结果)。我刚刚开始学习 C,并且很难理解其中的一些任务。

这是我尝试过的,但是当我输入 5、9 或 24 等数字时,我分别得到以下结果:0、4、4。

    if(x&(y-1)){ //if not 0 then multiple of y
        x = x&~(y-1) + y;
    }

非常感谢任何解释,幕后发生的数学示例。

编辑:所以澄清一下,我有点理解位的移位来确定一个项目是否是一个倍数。(正如在回复中解释的那样,10100 是 101 的倍数,因为它刚刚被转移)。如果我有数字 16,即 10000,它的补码是 01111。我将如何使用这个补码来查看一个项目是否是 16 的倍数?也有人可以对上面给出的代码进行数字解释吗?展示这一点可能有助于我理解为什么它不起作用。一旦我了解它为什么不起作用,我相信我将能够自己解决问题。

4

3 回答 3

1

您为什么还要考虑为此使用按位运算?他们当然有自己的位置,但事实并非如此。

更好的方法是简单地使用类似的东西:

unsigned multGreaterOrEqual(unsigned x, unsigned y) {
    if ((x % y) == 0)
        return x;
    return (x / y + 1) * y;
}
于 2015-03-24T03:45:22.593 回答
0

在平凡的情况下,每个是 2 的幂的偶数倍的数字都只是向左移动(这在可能改变符号位时不适用)

例如

10100

是 4 次

101

和 10100

是 2 次

1010

至于其他倍数,则必须通过组合两个班次的输出来找到它们。您可能想查找一些计算机除法的原始方法,其中除法看起来大致像

x = a / b

像实施

buffer = a
while a is bigger than b; do
  yes: subtract a from b
       add 1 to x
done

更快的例程首先尝试找出更高级别的位置值,跳过大量减法。所有这些例程都可以按位完成;但这是一个很大的痛苦。在 ALU 中,这些例程是按位完成的。可能想查找数字逻辑设计书以获取更多想法。

于 2015-03-24T03:48:25.667 回答
0

好的,所以我发现了我的代码中的错误,并且由于大多数人说不可能使用掩码计算一个数字是否是另一个数字的倍数,我想我会分享我所学到的。有可能的!- 如果您使用的是正确的数据类型。

如果 y 被声明为一个常量 unsigned long 并且传入的 x 也是一个 unsigned long ,那么上面给出的代码就可以工作。关键不是长或常数部分,而是数字是无符号的。此符号位会导致计算错误,因为数字中的第一位表示符号,并且在执行按位运算时,符号可能会变得混乱。

因此,如果我们要查找 16 的倍数,这是我的代码: const unsigned long y = 16; //在我的情况下全局声明

然后将一个 unsigned long 传递给运行以下代码的函数: if(x&(y-1)){ //if not 0 then multiple of y x = x&~(y-1) + y; x 现在将是 16 的最接近倍数的大小。

于 2015-03-25T22:35:11.537 回答