我看到过几个有类似背景的老帖子,但答案是代码片段,没有解释。我甚至不能得到这些答案中提供的代码来编译。
如果这是不好的格式或解释,我提前道歉,我是c++的新手,我尽量避免在论坛上提问,但这已经成为我真正的刺。
我正在使用c++访问加速度计的内存寄存器。该寄存器包含8位二进制补码形式的数据。
加速度计设置为+/- 2g的范围,这意味着(见参考手册第10页的1.5节)
我的目标是将这两个补码数据保存到一个文本文件中,作为基数为10的签名数据。
相关代码如下:
while(1)
{
int d = 0;
d= wiringPiI2CReadReg8(fd, DATA_X_H);
d = (int8_t)d;
d = d * EIGHTBITCONV;
std::cout << d << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
我已经通过硬编码测试了这个程序"如01111111(127),程序返回&;73&;。但是硬编码&;如10000001(-127),程序返回正确的"-127"
所以程序只有在处理负数时才能正常工作。
发生这种情况是因为在转换浮点数"d"一个8位的整数,它截断前导零为正数?我该如何解决这个问题?
数据表链接:https://www.mouser.com/datasheet/2/348/KX132-1211-Technical-Reference-Manual-Rev-1.0-1652679.pdf
-
您不需要将2的补码转换为"有符号整数",因为2的补码是签署了整数。
-
您只读取8位,但
int
(wiringPiI2CReadReg8
的返回类型)有更多。所以你需要一个扩展符号的转换。比如:
int result = (int)(signed char)wiringPiI2CReadReg8(fd, DATA_X_H);
(int)
转换是隐式的,可以省略。在您的情况下,您正在转换为浮点数(转换又是隐式的)。所以:
d = (signed char)wiringPiI2CReadReg8(fd, DATA_X_H);
实际上你的解决方案(否定两次)也会起作用。更明确地说,它可以这样写(因为1是int
):
d = -((int)(~(int8_t)d) + 1);
但这只是不必要的工作。可以简化为:
d = -(-(int8_t)d);
现在显然简化为:
d = (int8_t)d;
和我以前写的一样。
好的,所以我认为很多我的困惑来自这样一个事实,我试图硬编码值到我的程序没有适当的知识如何这样做。
如果我要硬编码作为测试逻辑的方法,我应该指定"d"二。
所以看起来我的原始代码,虽然非常潦草,但运行正常。