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. 105_Power Pivot财务科目(层级深度&筛选深度)

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 1.背景 在财务科目中,需要按照科目层级来显示:在excel中都是用公式来实现,而且对于数据的管理及更新是一件头痛的事情, ...

  2. ethtools-网卡适配器管理

    查看网卡适配器配置信息,并且我们可以通过它修改网卡适配器的双工模式. 1.安装Ethtools [root@localhost ~]# yum -y install ethtools 2.命令语法 语 ...

  3. MongoDB 常用启动参数

    每日一句 Once you choose your way of life, be brave to stick it out and never return. 生活的道路一旦选定,就要勇敢地走到底 ...

  4. 【SignalR全套系列】之在.Net Core 中实现SignalR实时通信

    ​ 微信公众号:趣编程ACE 关注可了解更多的.NET日常实战开发技巧,如需源码 请公众号后台留言 源码 [如果觉得本公众号对您有帮助,欢迎关注] 前文回顾 [SignalR全套系列]之在.NetCo ...

  5. 云原生存储解决方案Rook-Ceph与Rainbond结合的实践

    基础不牢,地动山摇.无论是何种体系架构,底层存储的选择都是一个值得探讨的话题.存储承载着业务的数据,其性能直接影响到业务应用的实际表现.也正因为存储和业务的数据关联紧密,其可靠性也必须得到关注,存储的 ...

  6. redisson之分布式锁实现原理(三)

    官网:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 一.什么是分布式锁 1.1.什么是分布式锁 分布式锁,即分布式系统中的锁 ...

  7. 关于升级最新版本node.js你知道多少?

    1.先检查版本 node -v 2.清除缓存 npm cache clean -f 3.全局安装管理node.js版本工具 npm install -g n 4.确认安装最新版本 n stable 5 ...

  8. 全新升级的AOP框架Dora.Interception[4]: 基于Lambda表达式的拦截器注册方式

    如果拦截器应用的目标类型是由自己定义的,Dora.Interception(github地址,觉得不错不妨给一颗星)可以在其类型或成员上标注InterceptorAttribute特性来应用对应的拦截 ...

  9. UiPath循环活动While的介绍和使用

    一.While循环的介绍 先判断条件是否满足, 如果满足, 再执行循环体, 直到判断条件不满足,则跳出循环 二.While循环在UiPath中的使用 1. 打开设计器,在设计库中新建一个Flowcha ...

  10. 【JS】两数之和

    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一 ...