按位运算符和位操作(没有解决方案?)

3

我一直在努力想出一个解决方案,但却卡住了。

我有一个函数,该函数接受输入(0b00b10b10),并设置某个变量的位 - 或者至少应该这样做。

它正在更改的值有两种状态:要么是0b100,要么是0b101。我想设置相应的位来匹配输入。这对于真正的位很容易,但对于假的位则很棘手。以下是所有方案的伪代码:

if (var == 0b100 && input == 0b0) { do nothing }   // bit already set
if (var == 0b101 && input == 0b0) { var = 0b100 }  // bit is different, so we set it.

if (var == 0b100 && input == 0b1) { var = 0b101 }  // bit is different, so we set it.
if (var == 0b101 && input == 0b1) { do nothing }   // bit is already set

if (var == 0b100 && input == 0b10) { var = 0b110 } // bit is never set, so set it
if (var == 0b101 && input == 0b10) { var = 0b110 } // bit is never set, so set it

我不想通过为每种可能性创建单独的语句来欺骗,我希望有一个函数可以实现这一点。以下是我拼凑出来的函数,但显然它不能正常工作:

if ( var ^ input )
{
    var ^= input;
}

这段代码的问题在于第三位(最左侧的一位)总是为真。
这真的可能吗?
编辑:
以下是同样的问题,只是提出了不同的方式(将导致不同的答案)。
一个函数需要输入一个二进制位。我想要取最左边的一位并将该位与另一个变量进行比较。例如,对比0b101的第二位0b00input = 0b10的最左边的一位,因为0b10的最左边的一位是第二个位置。
在极少数情况下,不变的位可能会改变:P(不是由我引起),因此0b0010b000可能是它的值。因此,我不能创建一个动态掩码并仅比较我的位...解决我的问题的最佳方法是回答这个替代问题。非常感谢你们的帮助!

5
在我看来,你所需做的就是 var = 0b100 | input - Some programmer dude
2
有很多工具可以完成这种事情,包括位运算符、移位运算符将输入转换为位索引、转移到状态机或使用布尔逻辑最小化工具,如卡诺图。如果没有关于您真正想要做什么的实际信息,很难给出一个好的答案。 - Zalman Stern
实际情况中有比我切换的最后一位更多的位。如果您愿意,我可以将示例更改为8位长,其中2个始终处于开启状态(不可更改),3个正在更改,而3个始终处于关闭状态(可更改)。也许这会帮助人们回答特定的示例问题。我是新来的,所以很抱歉 :) - J. Doe
你在上面的例子中所做的是 var = 0b100 + input。这样对吗? - Cris Luengo
输入始终集中在一个位上,顺便说一下!因此,如果有一种隔离和检查位的方法,那就太好了! :) - J. Doe
显示剩余11条评论
1个回答

2
步骤1:屏蔽掉最低的两位。
var &= 0b100;

步骤二:通过OR运算分配低两位。
var |= input;

请注意,根据实际数据类型,您可能需要在第1步中更改位掩码。

我宁愿在不知道变量是否已更改的情况下不设置变量:D 假设输入为 0b101,变量为 0b101,即使它已经是这样,我也会将变量设置为 0b101 - J. Doe
@J.Doe,你的问题中提到输入要么是0b00b1或者0b10。检查输入的有效性是这两个步骤之外的单独操作。而且你为什么想要避免“不必要地”设置变量呢? - user2486888
我已经在回复其他人时解释了,但我现在正在写入另一个程序的内存。这样做是不必要的,对于这个程序来说是很危险的,所以我想完全避免这样做。 - J. Doe
除非最终结果取决于已经存在的位的值,否则没有必要事先检查它们的值。有些操作是有意义的(想到一些字符串操作),但按位操作非常基础,你几乎必须在汇编级别上重复代码才能在赋值前检查值。 - SoronelHaetir
如果中间步骤让某人感到担忧,只需将这两个二进制操作合并为一个步骤。 - Christophe
如果你想防止写入其他程序内存中的变量,可以按照这个答案计算结果,然后将其与原始值进行比较,如果发生了改变,则将其写入内存位置。 - Cris Luengo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接