C++ 有符号字节和奇偶校验字节之间的差异

C++ 有符号字节和奇偶校验字节之间的差异,c++,byte,C++,Byte,我正在从字节流中读取一些字节,它们如下所示: OUTPUT: 48 -84 -79 -84 -73 -79 46 48 -84 SHOULD BE: 48 44 49 44 55 49 46 48 44 我想把这些转换成ascii字符,但是那些负数符号让我感到困惑。这让我觉得我不懂有符号字节。我到底做错了什么?将它们作为无符号字节读取 解释:当您将第一位(最高)解释为有符号字节时,它被视为+/-符号,而不是普通的二进制数字。它是一个8位有符号整数。类似于32位整数,但范围较小。应

我正在从字节流中读取一些字节,它们如下所示:

OUTPUT:
48 -84 -79 -84 -73 -79 46 48 -84

SHOULD BE:
48  44  49  44  55  49 46 48  44

我想把这些转换成ascii字符,但是那些负数符号让我感到困惑。这让我觉得我不懂有符号字节。我到底做错了什么?

将它们作为无符号字节读取


解释:当您将第一位(最高)解释为有符号字节时,它被视为+/-符号,而不是普通的二进制数字。

它是一个8位有符号整数。类似于32位整数,但范围较小。

应用程序可能在将其写入之前将其转换为整数。您用来生成输出的代码是什么?

什么是“字节”?在C++语言中,“字节”是与代码> char < /C> >类型的同义词,它只是一个可以被签名或未签名的普通整数类型。在您的平台上,类型
char
可能是有符号的(如果您使用的是
char
),这就是您获得有符号值的原因

换句话说,很可能您自己使用了带符号的类型来将值读入,因此预期您会得到带符号的结果

当然,这只是一个猜测,因为如果没有看到代码,就不可能说出您正在做什么。

例如:

 84 (dec): 0101 0100
-84 (dec): 1010 1100

 44 (dec): 0010 1100
后者(
-84
)是前者(
84
)的两个补充。对于有符号字节编码,如果设置了最高位,则表示负数


巧合的是,
44
(dec)在有符号字节中的编码类似于
-84
,但其最高位是清晰的。

很可能您关心的是7位ASCII字符集(例如,我们所有的英语人都在其中)。由于您一次读取8位,最简单的方法是屏蔽最高位(即符号位)

在C中:

字符字母=数据字节&0x7F


-84,其顶部位被屏蔽,是44。

当您从任何源(文件、网络套接字等)读取数据时,它只是一个由1和0组成的流。通常,它们是以八个字节(即字节)为一组交付的,但如何解释这些位完全取决于您的代码

假设文件包含以下字节:

10101100
如果将其解释为有符号字节,则表示十进制值-84

如果将其解释为无符号字节,则它表示十进制的值172


如果您的代码正在将值读入
char
类型的变量,那么您将看到-84,因为
char
在默认情况下是有符号的。如果将变量声明更改为
unsigned char
,则会看到172。在这两种情况下,基础位都是相同的,您只是告诉计算机以不同的方式解释它们。

看起来最高的位用作奇偶校验位,而您的代码假定它是符号位

  • 48=0110000:2位设置->添加0 ->0011 0000=48
  • 44=010 1100:3位设置->添加1 ->10101100=-84
  • 49=011 0001:3位设置->添加1->1011 0001=-79
  • 等等

解决方案:使用
(value&0x7f)
屏蔽最高位

@Stephano现在我们有进展了:)

UART最可能设置为7个数据位+1个奇偶校验位(高位为奇偶校验位),因此字节中的设置位数必须为偶数


您可以使用它进行错误检查,然后重置它以获得真正的7位ASCII字符。

发布读取它们的代码。什么逻辑可以将
48
转换为
48
,同时将
44
转换为
-84
?@ruslik:
char transform\u char(char c){if(c==48){return 48;}else if(c==44){return-84;}抛出char_not_44_或_48_exception();}
,自然。@ruslik IE6:)。说真的,我正在从串行端口读取并在actionscript中输出带符号的字节,所以在这里显示有意义的代码有点困难。@Stephano你从一开始就提到了神奇的单词
串行
。不完全正确。上面的值(无符号)0x80确实是负数,但它不是两个补码中的“符号位”。它也没有解释“应该是”和“输出”之间的关系。@Theartrus:更正确的定义是,最高有效位的十进制值为-128,而不是有符号8位值中的128。通俗地说,这被称为“符号位”几十年来。但是,如果您将“符号位”定义为狭义的“表示符号的位”,这是IEEE 754浮点运算中的工作方式,那么2的补码没有“符号位”。FWIW,调用此“符号位”定义表示0和-0的不同表示形式。+1我想这可以很好地解决问题。很抱歉,我无法更轻松地显示代码,但我会自己将其刷新。+1用于将我设置在正确的轨道上,以获得可接受的答案。哇。您是对的,先生。代码假定它是符号位,但它确实是奇偶校验位。做得好!+1d获胜。+1也是正确的。从技术上讲,斯霍尔德是在蜂鸣器的作用下进入的。干得好,伙计!我们都在正确的轨道上。直到我写下我的答案,我才看到你的评论。