博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
补码与符号位取反
阅读量:4658 次
发布时间:2019-06-09

本文共 1130 字,大约阅读时间需要 3 分钟。

补码与符号位取反

先来一个 C 语言的小例子:

#include 
#include
int main(void){ int16_t n = -1; n &= 0x7FFF; // 按位与 printf("%d", n); // 这里输出什么? return 0;}

对于16位的整数 n ,按位与运行将最高位设置为0(符号位),得到的结果却不是 1 ,结果是 32767 。

原因在于有符号整数的实现方式。

有符号整数,最容易想到的方式是在最高位加一个符号位,0表示整数,1表示负数,其它位不变(保留原始值),也即是原码方式。但这个方式有一个问题,存在两个0,正0和负0,在计算时需要先判断符号位,然后才能决定用加法还是减法,机器计算不便。

另外一个方法是负数全部按位取反,也就是反码方式。这个运算就相对简单了,进行加法时,按位计算,0和0为0,0为1为1,1和1为0并产生进位,最高位有进位时,结果要加1,减法可处理为其负数的加法。但还是有点问题,还存在两个0,正0和负0。

问题是出现负数上,那么把负数的反码 + 1 ,不就把负0去掉了吗?还真的是这样,而同时负数比整数能多表示一个数(这是基于同余的)。

严格的表达为:

对于位数为 n 的整数,其补码 [x]补 为:(2^n + x) mod 2^n ,表示的范围为 -2^(n-1) <= n < 2^(n-1) ,注意正数最大为 2^(n-1)-1即:当 0 <= x < 2^(n-1) 时,[x]补 = x 的原码当 -2^(n-1) <= x < 0 时,[x]补 = 2^n + x 的原码。

而经验上,可看作负数的补码为其反码加1(特殊数 -2^(n-1) ) 的反码 :

x < 0 时:[x]补 = [x]反 + 1特殊数 [ -2^(n-1) ] = 100...0

它的加法处理非常简单,符号位也可以运行,

[x+y]补 = (2^n + x + y) mod 2^n = ((2^n + x) + (2^n + y)) mod 2^n = [x]补 + [y]补[x-y]补 = (2^n + x - y) mod 2^n = ... = [x]补 + [-y]补

现在回到原来的问题,对于16位 -1 ,其补码为:

[-1]补 = [-1]反 + 1 = 0xFFFFF

按位与去掉符号位,得到的是 0x7FFF 也就是16位整数最大的正数( 2^15 - 1) 32767。

转载于:https://www.cnblogs.com/fengyc/p/6734887.html

你可能感兴趣的文章
【转】互联网时代的社会语言学:基于SNS的文本数据挖掘
查看>>
SEO (Search Engine Optimization)优化以及品牌知名度提升方法
查看>>
.Net Core Web Api 上传女朋友的照片到微软云Azure Storage
查看>>
【hdu 2176】取(m堆)石子游戏
查看>>
【u114】旅行计划(12月你好)
查看>>
JavaFX:禁止TableView的列拖拽功能
查看>>
6、ns-3数据跟踪
查看>>
java_js_避免无意义的条件判断
查看>>
Java并发程序设计(一) 基础概念
查看>>
Linux命令date日期时间和Unix时间戳互转
查看>>
LightOJ - 1297 Largest Box LightOJ(一元三次方程求极大值)
查看>>
883H - Palindromic Cut(思维+STL)
查看>>
.NET FTP上传文件
查看>>
操作系统中的调度算法
查看>>
JVM方法调用栈
查看>>
目标跟踪之Lukas-Kanade光流法
查看>>
python基础(第二课)
查看>>
C语言预处理条件语句的 与或运算
查看>>
D1图论最短路专题
查看>>
.Net core的日志系统
查看>>