c++ - 是比特集吗?仅当编写为 Oneliner 时,函数才返回错误结果
问题描述
对于测试某个位是否设置为无符号整数(16 位)值的函数的行为,我感到非常困惑。
我正在测试号码:57393(1110 0000 0011 0001)
非工作函数是
bool IsBitSet(int bit, unsigned int value)
{
return (((unsigned int)1) << bit) & value > 0;
}
测试bit = 0; bit < 7; bit++
我的功能得到结果:1 0 0 0 0 0
这显然是不正确的。
然后我将函数重写为单独的步骤:
bool IsBitSet(int bit, unsigned int value)
{
unsigned int test = ((unsigned int)1) << bit;
test = test & value;
if (test > 0) {
return true;
}
else {
return false;
}
}
在我看来,这应该完全一样。但是现在我得到了正确的输出:1 0 0 0 1 1
.
鉴于对 C++ 的经验很少,我无法弄清楚这两个函数之间的区别是什么。我可以保留更长的功能,但我想了解我哪里出错了,以免再次遇到这种情况。
该代码是为 Arduino 平台编译的,由于字长或编译器行为,这可能很重要。
解决方案
原来我找到了答案。我遇到了运算符优先级的问题。做的时候
(((unsigned int)1) << bit) & value > 0
大于运算符>
优先于按位与运算符&
,因此value > 0
首先评估为 bool true,它被隐式转换为 1。
然后(((unsigned int)1) << bit) & 1
被评估,给出1
if bit=0
,或0
在其他情况下。然后该值再次隐式转换为 bool 以返回。
所以问题是没有警告地考虑运算符优先级和隐式转换。逐步运行函数,优先级没有问题,因为比较总是在按位与之后进行。
Oneliner 可以使用附加支架进行固定:
return ((((unsigned int)1) << bit) & value) > 0;
推荐阅读
- java - lombok builder() 方法有一条红线
- node.js - Nodejs child_process exec没有运行/bin/bash
- ios - 如何从视图控制器跟踪表格视图单元格的文本字段文本?
- c# - 具有多个集合的 ASP.NET Core Web API 和 MongoDB
- python - python.net用自定义控件构造WPF窗口
- ios - 如何在 UIKit 中使用 ZStack
- ansible - 重用剧本并从主剧本传递主机
- python - 从存在于长度字符串中的冗长列表中返回元素
- php - 如何在 laravel 7 中将公用文件夹更改为 public_html?
- django - 通过表单在 Django 中创建用户