C# 从补码中获取有符号数的实际数值

原理

计算机存储数据时,默认是存储数据的补码。有符号的数粗存在符号位(最高位)。

这里就会提到原码、反码、补码的概念。

原码:用符号位和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。

反码:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。

补码:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.

思路

下位机上传有符号数时,直接上传的是补码。上位机解析时,需要手动转换:

一、当数为负数时。

0.获取该数据的补码,去掉最高位(符号位)并将其合并到一个结构体中(数据通信一般以字节为单位)。

1.空位(不用的位)补全,高位不用的置1。

2.将补码-1

3.然后再取反

4.乘上比例尺与-1

二、当数为正数时。

0.获取该数据的补码,去掉最高位(符号位)并将其合并到一个结构体中(数据通信一般以字节为单位)。

1.乘上比例尺

示例

下位机上传的数据中有8个字节,其中第4(从0开始)字节的低四位和第5字节的高7位组成一个参数,这个参数是有符号的数据,与整数之间的比例尺是0.1。要求解析出该参数。

代码

// 获取数据

byte[] data = new byte[8];

data = GetDataFromUsb();

            // 解析数据
// 当上传的数据为负数时
if ((UInt16)(data[4] & 0x08) == 0x08)
{
// 去掉最高位获取数据
UInt16 s = (UInt16)(((data[4] & 0x07) << 7) + (UInt16)((data[5] >> 1) & 0x7F)); // 空位补全,高位不用的置1
UInt16 s1 = (UInt16)(s | 0xFC00); // 补码-1
UInt16 s2 = (UInt16)(s1 - 1); // 取反
UInt16 s3 = (UInt16)~s2; // 乘上-1和比例尺
_Speed = -(s3 * 0.1f);
}
// 当待解析的数据为正数时
else
{
// 去掉最高位获取数据
UInt16 s = (UInt16)(((data[4] & 0x07) << 7) + (UInt16)((data[5] >> 1) & 0x7F)); // 乘上比例尺
_Speed = s * 0.1f;
}

图表解释

1._Speed参数的占位情况。

7 6 5 4 3 2 1 0

data[4] F_Speed _Speed _Speed _Speed

data[5] _Speed _Speed _Speed _Speed _Speed _Speed _Speed

其中data[4]的第3位为我们符号位,也就是F_Speed。当我们做有符号码转换时,可以直接忽略,因为他不影响我们真实值的改变。

2.空位补全缘由

当我们使用更大的空间来做容器填充数据时,负数的空位补全。

UInt16也就等于2个字节

第0步运算之后,我们数据如下图所示。

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

_S _S _S _S _S _S _S _S _S _S

我们知道,上面的所有_S的数据都是元数据的补码,因为该数是负数,所以我们需要将这个数据的符号位置为1,其它未使用的位(14、13、12、11、10)也置为1。这样我们就可以通过-1再求反码得到负数的值了。

版权声明:本文为CSDN博主「一阵没来由的风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/YouyoMei/article/details/105880627

C# 从补码中获取有符号数的实际数值的更多相关文章

  1. 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字

    上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...

  2. verilog中的有符号数运算

    verilog中的有符号数运算 http://hi.baidu.com/lixu1113/item/d00dc095f86aed48f142159a verilog中的有符号数运算 有符号数的计算:若 ...

  3. verilog中的有符号数理解(转)

    verilog中的有符号数运算 有符号数的计算:若有需要关于有号数的计算,应当利用Verilog 2001所提供的signed及$signed()机制. Ex: input  signed [7:0] ...

  4. Android中获取TextView行数

    项目中发现,如果直接通过TextView.getLineCount()方法获取行数时,总是0,研究发现,setText()后立即调用getLineCount(), 这时TextView还未完成meas ...

  5. layui中从内置的分页中获取总记录数(转)

    封装的工具类: https://blog.csdn.net/QYHuiiQ/article/details/82147537

  6. Verilog有符号数处理

    内容主要摘自以下两个链接:  https://www.cnblogs.com/LJWJL/p/3481995.html  https://www.cnblogs.com/LJWJL/p/3481807 ...

  7. 关于有符号数和无符号数的转换 - C/C++

    转载自:http://www.94cto.com/index/Article/content/id/59973.html 1.引例: 今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题, ...

  8. 从Linux内核中获取真随机数【转】

    转自:http://www.cnblogs.com/bigship/archive/2010/04/04/1704228.html 内核随机数产生器 Linux内核实现了一个随机数产生器,从理论上说这 ...

  9. oracle 与sql serve 获取随机行数的数据

    Oracle 随机获取N条数据    当我们获取数据时,可能会有这样的需求,即每次从表中获取数据时,是随机获取一定的记录,而不是每次都获取一样的数据,这时我们可以采取Oracle内部一些函数,来达到这 ...

随机推荐

  1. 女朋友面试回来抱怨说会redis,面试官问了一堆redis

    Redis 优缺点及特点 什么是Redis?简述它的优缺点? Redis本质上是一个Key-Value类型的内存数据库,类似MemoryCache,整个数据库统统加载在内存当中进行操作,定期通过异步操 ...

  2. ptorch常用代码梯度篇(梯度裁剪、梯度累积、冻结预训练层等)

    梯度裁剪(Gradient Clipping) 在训练比较深或者循环神经网络模型的过程中,我们有可能发生梯度爆炸的情况,这样会导致我们模型训练无法收敛. 我们可以采取一个简单的策略来避免梯度的爆炸,那 ...

  3. python3在使用类基础时,遇到错误TypeError: module.**init**() takes at most 2 arguments (3 given)

    python3在使用类基础时,遇到错误TypeError: module.init() takes at most 2 arguments (3 given) 1.原因:直接导入的py文件,而没有导入 ...

  4. bintree

    Python实现二叉树的建立与遍历 创建(二叉)树节点类 class Node: def __init__(self,data,l=None,r=None): self.val = data self ...

  5. DirectX11 With Windows SDK--19(Dev) 编译Assimp并加载模型、新的Effects框架

    前言 注意:这一章进行了重写,对应教程Dev分支第19章的项目,在更新完后面的项目后会替换掉原来第19章的教程 在前面的章节中我们一直使用的是由代码生成的几何模型,但现在我们希望能够导入模型设计师生成 ...

  6. java提前工作、第一个程序

    java提前工作 我们学习编程肯定会 运用到相应的软件 在这里 我个人推荐 eclipse.idea 这里的软件呢 都是用我们的java编程出来的,那它也需要用java来支持他的开发环境 这里就运用到 ...

  7. Citus 11 for Postgres 完全开源,可从任何节点查询(Citus 官方博客)

    Citus 11.0 来了! Citus 是一个 PostgreSQL 扩展,它为 PostgreSQL 添加了分布式数据库的超能力. 使用 Citus,您可以创建跨 PostgreSQL 节点集群透 ...

  8. UiPath选择器之页面选择器的介绍和使用

    一.页面选择器的介绍 某些软件程序的布局和属性节点具有易变的值,例如某些Web应用程序.UiPath Studio无法预测这些变化,因此,您可能必须手动生成一些选择器. 每个属性都有一个分配的值.选择 ...

  9. 浪姐打分看不够?用几行Python代码模拟评委打分

    大家好鸭~我是小熊猫比赛大家都看过吧,每次是不是都对比赛成绩充满期待.特别是浪姐的打分看的简直欲罢不能- 今天就用Python来模拟评委打分,这个案例很短也很简单,很适合新手跟小白练习. 在某次十佳歌 ...

  10. Python列表解析式的正确使用方式(二)

    高级解析式 条件逻辑早些时候,我向您展示了这个公式: python学习交流群:660193417### new_list = [expression for member in iterable] 公 ...