负数取反,单目运算“-”的运算

首先看代码:

int main(){
   int i=-2147483648;
   return printf("%d,%d,%d,%d",~i,-i,1-i,-1-i);
}

输出结果为:

2147483647,-2147483648,-2147483647,2147483647

这里就涉及到对负数取反,单目运算符“-”的理解,在int占4个字节,大小范围为-2147483648~2147483648,最高位代表符号位,所以第32位为1,这里就需要理解计算机中负数的表示形式:

计算机中的数字都是以补码的形式存放!

正数的原码、反码、补码都相同

5在计算机中原码、反码、补码均为:00000000 00000000 00000000 00000101

负数的反码为对该数的原码除符号位外各位取反,补码为其反码加1:

-5原码为:10000000 00000000 00000000 00000101

反码为:11111111 11111111 11111111 11111010

补码为:11111111 11111111 11111111 11111011

所以-5在计算机中存储形式为11111111 11111111 11111111 11111011转换为十六进制为:0xFFFFFFFB

但是-2147483648比较特殊!

-2147483648原码为:10000000  00000000  00000000  00000000 (表示-0)

反码为:11111111 11111111 11111111 11111111

补码为:00000000  00000000  00000000  00000000

+0的原码、补码、反码均为00000000  00000000  00000000  00000000

如果用-2147483648用补码00000000  00000000  00000000  00000000来表示则和0的补码一样,不能区分开;

所以计算机规定用10000000 00000000 00000000 00000000来表示-2147483648的补码,

32位最小负整数的补码为10000000 00000000 00000000 00000000

计算机中-2147483648取反为:01111111 11111111 11111111 11111111,此为存储正数的补码,换算原码得到数为2147483647

单目运算符“-”为取负,-2147483648取负为2147483648,显然超过int类型范围(-2147483648~2147483647),刚好超过一个就变为-2147483648,所以其对应的补码仍为10000000 00000000 00000000 00000000,

对应补码理解就是-x=~x+1;即补码取反加1,10000000 00000000 00000000 00000000取反加1后任然为10000000 00000000 00000000 00000000,对应数为-2147483648

1-i为(-i)+1,对应补码为:

10000000 00000000 00000000 00000000+00000000 00000000 00000000 00000001=10000000 00000000 00000000 00000001

转换为十进制为:- 2147483647

-1-i为(-i)+(-1),对应补码为:

10000000 00000000 00000000 00000000+11111111 11111111 11111111 11111111=01111111 11111111 11111111 11111111

转换为十进制为: 2147483647

其实也可以从十进制理解:-2147483648-1=-2147483649,超过范围后变为2147483647

原文地址:https://www.cnblogs.com/xiaodingmu/p/8215613.html

时间: 2024-10-15 08:20:22

负数取反,单目运算“-”的运算的相关文章

正负数取反的结果和规律

按位取反运计算方法原创 jackytse_ 最后发布于2012-10-29 14:27:01 阅读数 11247 收藏展开 读本文前请首先搞懂  “反码”,“取反”,“按位取反(~)”,这3个概念是不一样的. 取反:0变1,1变0 反码:正数的反码是其本身,对于负数其符号位不变其它各位取反(0变1,1变0) 按位取反(~): 这将是下面要讨论的. “~”运算符在c.c++.java.c#中都有,之前一直没有遇到这个运算符. 要弄懂这个运算符的计算方法,首先必须明白二进制数在内存中的存放形式,二进

C的|、||、&、&&、异或、~、!运算 位运算

研究这个的起因是我遇到一个题目,判断一个数是奇偶数,这个很简单,但是又个最佳代码 判断奇偶时用了 #include int main() { int n; scanf("%d",&n); printf("%s",n&1?"odd":"even"); } 这里用&运算,从而判断二进制数的最后一位是否为当n的最后一位=0.和1& 则为 0 .只有当n = 1 则 &为 1 再根据?:表达式的

位运算常用操作总结位运算应用口诀清零取反要用与,某位置一可用或若要取反和交换,轻轻松松用异或移位运

来源:http://www.educity.cn/wenda/381487.html 位运算常用操作总结位运算应用口诀 清零取反要用与,某位置一可用或 若要取反和交换,轻轻松松用异或 移位运算 要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形.     2 " $amp;     3 "$amp;>amp;>quot;$右移:右边的位被挤掉.对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统.     4 "

php位运算 与 或 异或 取反

<?php /** php中有4个位运算,分别是&与 |或 ^异或 ~取反 & 两位全为1,结果为1 | 有一位为1,结果为1 ^ 一个为0,一个为1,结果为1 ~ 取反0->1,1->0 1.二进制的最高位是符号位,0表示正数,1表示负数. 2.正数的原码,反码,补码都一样. 3.负数的反码=它的原码符号位不变,其它位取反(0->1,1->0). 4.负数的补码=它的反码+1. 5.0的反码,补码都是0. 6.php没有无符号数,换言之,php中的数都是有符

关于取反~的运算

今天看到一个东西 SELECT ~32767 ----------- -32768 按位反的话为什么结果为什么不是-520而是-521呢? 然后我又看了看,才想起在二进制的世界里,第一个数位是表示正负数,所以在smallint 的2字节里面,是这样纸的 32767 0111 1111 1111 1111 所以当取反的时候就是 -32768 10 0000 0000 0000 有时候就是转不过弯,不确定的时候还是要动手看下才能巩固自己的只是

C语言位运算符:与、或、异或、取反、左移和右移

语言位运算符:与.或.异或.取反.左移和右移 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型. C语言提供的位运算符列表:运算符 含义 描述& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1~ 取反 ~

【转】C语言位运算符:与、或、异或、取反、左移与右移详细介绍

转载自:http://www.jb51.net/article/40559.htm,感谢原作者. 以下是对C语言中的位运算符:与.或.异或.取反.左移与右移进行了详细的分析介绍,需要的朋友可以过来参考下 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型. C语言提供的位运算符列表:运算符 含义 描述& 按位与 如果两个相应的二进制位都为1,则该位

PHP中关于位运算符 与 或 异或 取反

<?php /** * author:LMS * createTime:2015/07/22 * desctiption:位运算[ & | ^ ~ ] * 与&:如果a.b两个值不相同,则与结果为0.如果a.b两个值相同,与结果为1 * 或|:与逻辑中的或一致[只有两个值都为假时才为假,其余都为真] * 异或[xor]如果a.b两个值不相同,则异或结果为1.如果a.b两个值相同,异或结果为0 * 取反[~]:对每一位取反 * [注意!非 ==>是逻辑运算符,返回是个布尔值 */

C语言----取反~

一.正数 (1)执行~0001后 为1110(内存中就是这样存储0001取反的结果的) 这个结果是以补码的方式存储的 但是真真的显示的时候往往用原码,就是1010了<最高位为符号位,这里为1,就是负号,010为2,所以结果为-2,原码的显示是为了直观,真真的运算都是以补码来运算的> ~0001的结果就是-2,-2的原码就是1010,补码为1110 (2)25在内存中的存储为:0000 0000 0001 1001 就是~25=1111 1111 1110 0110<内存中储存这个结果&g