手动转换签名字符
我正在使用一些嵌入式硬件,即 Rabbit SBC,它使用 Dynamic C 9。
我正在使用微控制器通过其串行端口之一从数字罗盘传感器读取信息。
传感器使用单个带符号字节将值发送到微控制器。 (-85 到 85)
当我收到此数据时,我将其放入 char
变量中,
这对于正值来说效果很好,但是当传感器开始发送负值时,读数会跳至 255,然后返回到 0。我认为这是因为最后一位用于确定负/正,并且扭曲了实际值。
我最初的想法是将数据类型更改为 signed char
。
然而,我遇到的问题是,我使用的微控制器上的 Dynamic C 版本本身不支持有符号的 char 值,仅支持无符号。
我想知道是否有办法手动将我收到的数据转换为有符号值?
I'm working with some embedded hardware, a Rabbit SBC, which uses Dynamic C 9.
I'm using the microcontroller to read information from a digital compass sensor using one of its serial ports.
The sensor sends values to the microcontroller using a single signed byte. (-85 to 85)
When I receive this data, I am putting it into a char
variable
This works fine for positive values, but when the sensor starts to send negative values, the reading jumps to 255, then works its way back down to 0. I presume this is because the last bit is being used to determine the negative/positive, and is skewing the real values.
My inital thought was to change my data type to a signed char
.
However, the problem I have is that the version of Dynamic C on the Microcontroller I am using does not natively support signed char values, only unsigned.
I am wondering if there is a way to manually cast the data I receive into a signed value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(4)
有符号和无符号值都只是一堆位,您的解释使它们成为有符号或无符号的。例如,如果您的硬件生成 2 的补码,如果您读取 0xff,您可以将其解释为 -1 或 255,但它们实际上是相同的数字。
现在,如果您只有 unsigned char
可供使用,则必须用它来模拟负值的行为。
例如:
c < 0
更改为
c > 127
Luckyly,加法不需要更改。减法也是一样的(检查一下我不是100%确定)。
例如,对于乘法,您需要自己检查。首先,在 2 的补码中,以下是如何获得数字的正值:
pos_c = ~neg_c+1
从数学上讲是 256-neg_c
,同余模 256 就是 -neg_c
code>
现在假设您想要将两个无符号数字相乘,但您希望将它们解释为有符号数字。
unsigned char abs_a = a, abs_b = b;
char final_sign = 0; // 0 for positive, 1 for negative
if (a > 128)
{
abs_a = ~a+1
final_sign = 1-final_sign;
}
if (b > 128)
{
abs_b = ~b+1
final_sign = 1-final_sign;
}
result = abs_a*abs_b;
if (sign == 1)
result = ~result+1;
你明白了!
如果您的平台支持signed int
,请查看其他一些答案。
如果不是,并且该值肯定在 -85 和 +85 之间,并且它是二进制补码,请将 85 添加到输入值并计算出程序逻辑来解释 0 到 170 之间的值,这样您就不必弄乱有符号不再是整数了。
如果它是补码,请尝试以下操作:
if (x >= 128) {
x = 85 - (x ^ 0xff);
} else {
x = x + 85;
}
这也会得到 0 到 170 之间的值。
编辑:是的,还有符号大小。然后在此处使用相同的代码,但将第二行更改为 x = 85 - (x & 0x7f)
。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您只需拿出参考书并阅读控制器如何表示负数。剩下的就是打字了。
例如,二进制补码通过取模 256 来表示,因此只需按模数进行调整即可。
一个的补码要简单得多:只需翻转位即可。
Sign-magnitude 通过设置高位来表示负数,因此只需清除该位并取反即可:
You just need to pull out your reference book and read how negative numbers are represented by your controller. The rest is just typing.
For example, two's complement is represented by taking the value mod 256, so you just need to adjust by the modulus.
One's complement is much simpler: You just flip the bits.
Sign-magnitude represents negative numbers by setting the high bit, so you just need to clear the bit and negate: