简体   繁体   English

将传感器数据(二进制补码)转换为有符号整数

[英]Converting sensor data (two's complement) to signed integer

I've seen a couple old posts that had a similar context but the answers were code snippets, not explanatory.我看过一些有类似背景的旧帖子,但答案是代码片段,而不是解释性的。 And I can't even get the code offered in those answers to compile.而且我什至无法获得这些答案中提供的代码进行编译。

I apologize in advance if this is poorly formatted or explained, I am new to C++ and I avoid asking questions on forums at all costs but this has become a real thorn in my side.如果格式或解释不当,我提前道歉,我是 C++ 新手,我不惜一切代价避免在论坛上提问,但这已成为我的真正眼中钉。

I am using C++ to access the memory register of an accelerometer.我正在使用 C++ 访问加速度计的内存寄存器。 This register contains 8 bits of data in the form of twos complement.该寄存器包含 8 位二进制补码形式的数据。

The accelerometer is set to have a range of +/- 2 g's, meaning (see section 1.5 of reference manual on page 10)加速度计的范围设置为 +/- 2 g,这意味着(参见第 10 页参考手册的第 1.5 节)

My goal is to take this twos complement data and save it to a text file as signed base-10 data.我的目标是获取这个二进制补码数据并将其作为带符号的 base-10 数据保存到文本文件中。

Relevant code below:相关代码如下:

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

I've tested the program by hard coding "d" as 01111111 (127) and the program returns "73".我已经通过将“d”硬编码为 01111111(127)来测试程序,并且程序返回“73”。 But hard coding "d" as 10000001 (-127) and the program returns the correct "-127".但是将“d”硬编码为 10000001 (-127) 并且程序返回正确的“-127”。

So the program only functions properly when dealing with negative numbers.所以程序只有在处理负数时才能正常运行。

Is this happening because when casting the float "d" to an 8bit integer it truncates the leading zero for positive numbers?发生这种情况是因为当将浮点数“d”转换为 8 位整数时,它会截断正数的前导零? How would I fix this?我将如何解决这个问题?


Link to datasheet: https://www.mouser.com/datasheet/2/348/KX132-1211-Technical-Reference-Manual-Rev-1.0-1652679.pdf数据表链接:https: //www.mouser.com/datasheet/2/348/KX132-1211-Technical-Reference-Manual-Rev-1.0-1652679.pdf

  1. You do not need to convert from 2's complement to "signed integer", because 2's complement is signed integer.您不需要将 2 的补码转换为“有符号整数”,因为 2 的补码是有符号整数。

  2. You are only reading 8 bits, but int (the return type of wiringPiI2CReadReg8 ) has more.您只读取 8 位,但intwiringPiI2CReadReg8的返回类型)有更多。 So you need a sign-extend conversion.所以你需要一个符号扩展转换。 Something like:就像是:

int result = (int)(signed char)wiringPiI2CReadReg8(fd, DATA_X_H);

The (int) conversion is implicit and can be omitted. (int)转换是隐式的,可以省略。 And in your case you are converting to a float (The conversion is again implicit).在您的情况下,您正在转换为浮点数(转换再次是隐式的)。 So:所以:

d = (signed char)wiringPiI2CReadReg8(fd, DATA_X_H);

Actually your solution (negating twice) would work as well.实际上,您的解决方案(两次否定)也可以。 More explicitly it could be written like this (since 1 is int ):更明确地说,它可以这样写(因为 1 是int ):

 d = -((int)(~(int8_t)d) + 1);

But this is just unnecessary work.但这只是不必要的工作。 It could be simplified to be:可以简化为:

d = -(-(int8_t)d);

and now it is obviously simplifies into:现在它显然简化为:

d = (int8_t)d;

same as what I wrote before.和我之前写的一样。

Ok so I think a lot of my confusion came from the fact that I was trying hard code values into my program without proper knowledge of how to do so.好的,所以我认为我的很多困惑来自这样一个事实,即我在没有正确知识的情况下尝试将代码值硬编码到我的程序中。

If I were to do hard coding as a method to test the logic, I should have specified that the values of "d" were binary.如果我要进行硬编码作为测试逻辑的方法,我应该指定“d”的值是二进制的。

So it looks like my original code, while extremely sloppy, was functioning properly.所以看起来我的原始代码虽然非常草率,但运行正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM