C# 从补码中获取有符号数的实际数值
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# 从补码中获取有符号数的实际数值的更多相关文章
- 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字
上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...
- verilog中的有符号数运算
verilog中的有符号数运算 http://hi.baidu.com/lixu1113/item/d00dc095f86aed48f142159a verilog中的有符号数运算 有符号数的计算:若 ...
- verilog中的有符号数理解(转)
verilog中的有符号数运算 有符号数的计算:若有需要关于有号数的计算,应当利用Verilog 2001所提供的signed及$signed()机制. Ex: input signed [7:0] ...
- Android中获取TextView行数
项目中发现,如果直接通过TextView.getLineCount()方法获取行数时,总是0,研究发现,setText()后立即调用getLineCount(), 这时TextView还未完成meas ...
- layui中从内置的分页中获取总记录数(转)
封装的工具类: https://blog.csdn.net/QYHuiiQ/article/details/82147537
- Verilog有符号数处理
内容主要摘自以下两个链接: https://www.cnblogs.com/LJWJL/p/3481995.html https://www.cnblogs.com/LJWJL/p/3481807 ...
- 关于有符号数和无符号数的转换 - C/C++
转载自:http://www.94cto.com/index/Article/content/id/59973.html 1.引例: 今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题, ...
- 从Linux内核中获取真随机数【转】
转自:http://www.cnblogs.com/bigship/archive/2010/04/04/1704228.html 内核随机数产生器 Linux内核实现了一个随机数产生器,从理论上说这 ...
- oracle 与sql serve 获取随机行数的数据
Oracle 随机获取N条数据 当我们获取数据时,可能会有这样的需求,即每次从表中获取数据时,是随机获取一定的记录,而不是每次都获取一样的数据,这时我们可以采取Oracle内部一些函数,来达到这 ...
随机推荐
- mysqldump速查手册
一.mysqldump用法 1.1 常见选项 --all-databases, -A: 备份所有数据库 --databases, -B: 用于备份多个数据库,如果没有该选项,mysqldump把第一个 ...
- 判断数据类型(typeof&instanceof&toString)
一.数据类型 ES6规范中有7种数据类型,分别是基本类型和引用类型两大类 基本类型(简单类型.原始类型):String.Number.Boolean.Null.Undefined.Symbol 引用类 ...
- 使用pdfcrack & crunch暴力破解PDF密码
crunch是密码字典生成器,可以根据指定的字符来生成组合密码字典. pdfcrack是Linux下一个PDF暴力破解密工具,可以使用crunch生成的密码字典来暴力破解PDF文件的密码. 注:没有强 ...
- 使用 Nocalhost 开发 Rainbond 上的微服务应用
本文将介绍如何使用 Nocalhost 快速开发 Rainbond 上的微服务应用的开发流程以及实践操作步骤. Nocalhost 可以直接在 Kubernetes 中开发应用,Rainbond 可以 ...
- Hash表、 继承
Hash表 我们来了解什么是Hash表?? 要想知道什么是哈希表,那得先了解哈希函数 二叉平衡树 红黑树 B B+树,它们的查找都是先从根节点进行查找,从节点取出数据或索引与查找值进行比较.那么,有没 ...
- 【Java面试】Mybatis中#{}和${}的区别是什么?
一个工作2年的粉丝,被问到一个Mybatis里面的基础问题. 他跑过来调戏我,说Mic老师,你要是能把这个问题回答到一定高度,请我和一个月奶茶. 这个问题是: "Mybatis里面#{}和$ ...
- Ubuntu Linux处理Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 3365 (unattended-upgr)问题
问题 在Ubuntu中,执行apt install后,出现以下问题: Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-fro ...
- HTML\Flex tips
相关文档 HTML:https://www.w3school.com.cn/html/index.asp bootstrap-css: https://v3.bootcss.com/css/#form ...
- Spring Data JPA系列5:让IDEA自动帮你写JPA实体定义代码
大家好,又见面了. 这是本系列的最后一篇文档啦,先来回顾下前面4篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring Data JPA,傻傻分不清楚?给你 ...
- 从Mpx资源构建优化看splitChunks代码分割
背景 MPX是滴滴出品的一款增强型小程序跨端框架,其核心是对原生小程序功能的增强.具体的使用不是本文讨论的范畴,想了解更多可以去官网了解更多. 回到正题,使用MPX开发小程序有一段时间了,该框架对不同 ...