ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

有符号数在计算机中的存储及在C语言中的运用

2020-02-22 19:52:45  阅读:401  来源: 互联网

标签:存储 0000 0xFE0 补码 取反 C语言 ch2 寄存器 数在


前言:近期在调试一个博世的三轴加速度传感器时,在用c写有符号数相关的运算和操作相关的代码时,进一步去理解了有符号数的应用。


首先在阅读相关文档时,发现了对寄存器描述中出现Two's complement,实际是为了说明该寄存器读出的值是以补码的形式存储,假设有两个八位寄存器,第一个寄存器中有低四位(LSB)和第二个寄存器有高八位(MSB)组成了一个12位的数据,这12位数据以补码的形式读出,其中最高位表示的是符号,即在代码运算操作时要将该补码进行转换成源码操作
譬如:读出的数是0xFE0 -> 0b1111 1110 0000
这是一个负数,此时要将再取补操作,即取反加一
取反:0b0000 0001 1111 加一:0b0000 0010 0000 -> 32(十进制)
++取反操作编程时:直接~(0xFE0) 或 0xFFF - 0xFE0++

(1)、但需要注意的是取反~操作计算机是相对于8位/16位/32位为单位每一位取反的,譬如这里定义16位操作int16_t(0xFE0),那么每一位都按位取反int16_t(~0xFE0),得到0xF01F(0b‭111 1 0000 0001 1111‬ );这样相对于12位有符号数的操作是不对的;其次正确按照 0xFFF - 0xFE0这样取反操作,int16_t(0xFE0)这样相对于16位数的操作来说这是一个正数,但是对于12位寄存器(bit11表示负数),所以取反加一后再加一个“-”号(因为负数反码的最高位是不变的),当成一个十进制数在代码中操作,所以推荐使用“-(0xFFF-0xFE0 +1)”这样的写法

  • [x] 注意在实际中计算机是按16位操作与实际寄存器要按12位有符号数的操作的区别
  • [x] 负数原码取反码,最高位不变;计算机在执行操作时譬如是按取反(~)操作,最高位就为0变成正数,最后需要我们手动添加负号
int16_t x;
x =( i2c_read_byte(0x02) &0xf0)>>4;
x=x|((i2c_read_byte(0x03)&0xff)<<4);//12bit
if(x>(0xfff/2))
{
x=-(0xfff-x);
}
x=(x*9.8)/(0xfff/2/2);//当量程为±2g时,转换为g/s的加速度换算公式

(2)如果正好是16位的寄存器,假设读出来的值是0x8FE0 -> 0b1000 1111 1110 0000,计算机取反时最高位是不变的
取反:0b0111 0000 0001 1111 (0xFFFF-0x8FE0)
加一:0b0111 0000 0010 0000
==注==:因为计算机取反(~)是每一位都取反,实际取反码最高位为1表示负数是不变的即最高位不动其他位取反,所以按照我们这样的操作最后在取反加一后,还要加“-”负号,相当于把“符号位被翻转成正后”的负号再找回来

有符号数计算存储测试:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   int ch1 = 0x00000001;//0b1000 0001;  
   int ch2 = 0x80000002;//0b1000 0010;  
   //这里的0x80000002并不代表十进制-2;这里只是某一个负数所存储的补码,这个负数为
   //-2147483646
   int ch3 = ch1 + ch2;
   if(((ch2&0x80000000)>>31) > 0)
   {
   printf("ch1 = %d\n", ch1); //1
   printf("ch2 = %x\n", ~ch2);  //7ffffffd
   printf("ch1 + ch2 = %d\n", ch3); //-2147483645
   printf("ch1 + ch2 = %x\n", ch3); //80000003
   }

   return(0);
}

更多有关内容可参考阅读:
1.关于Two's complement
2.原码反码补码的相互转换
3.计算机中带符号的整数为何采用二进制的补码进行存储
4.计算机中的有符号数都是以二进制的补码形式存储的

标签:存储,0000,0xFE0,补码,取反,C语言,ch2,寄存器,数在
来源: https://www.cnblogs.com/muziyu/p/12346823.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有