Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1658119
  • 博文数量: 695
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4027
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-20 21:22
文章分类

全部博文(695)

文章存档

2018年(18)

2017年(74)

2016年(170)

2015年(102)

2014年(276)

2013年(55)

分类: C/C++

2014-04-09 23:06:11

http://blog.csdn.net/zabcd117/article/details/1687413
(貌似有点小错误:先减1
1111 1111 1111 1111 1111 1111 1111 1110
再取反
0000 0000 0000 0000 0000 0000 0000 0001
取反时候,符号位不能变化)


今天在sqlserver里面创建表时用到了int型数据类型,长度只能为4,我就以为最大可以表示为9999,罪过啊。因为受char类型的影响,char的长度如果为4,则我只能输

入'abcd','qwer'这么长,再长的会被截断。其实int中的4代表4个字节,1个字节是8个二进制串,于是实际上int型可以表示的最大整数就是
0111 1111 1111 1111 1111 1111 1111 1111
共32位,最前面的一位是符号位,计算机中通常用0代表整数,1代表负数,于是这个数转换成10进制就是
2^0 + 2^1 + 2^2 + ……… 2^31 = 2^32 - 1 = 2147483647
于是,我又想当然的认为最小的负整数就一定是
1111 1111 1111 1111 1111 1111 1111 1111
我们知道,负数在计算机中是以补码的形式存储的,而负数的补码= 其绝对值的原码取反 + 1,我们可以反向来推算嘛
先减1
1111 1111 1111 1111 1111 1111 1111 1110
再取反
0000 0000 0000 0000 0000 0000 0000 0001
结果是这个很长看起来很小的数结果是-1,最大的负整数。那么int型能表示的最小的负整数到底是多少呢?暂时还不知道,但是有一点可以清楚的是,至少最前面一位是1,同时

发现如果我1存在的越多,好像越大,那么最小的负数就是1最少的那一个了
1000 0000 0000 0000 0000 0000 0000 0001
这样我先减去1,再取反以后就是
0111 1111 1111 1111 1111 1111 1111 1111
于是我又得出int型可表示的最小负数就是-2147483647,但是,实际上,我们知道人们规定了int型最小的负整数是-2147483648,确实比上面还小1,2进制就是
1000 0000 0000 0000 0000 0000 0000 0000
很奇怪的吧,但是这是规定,就像是1+1=2一样,其实,自己想想,蛮有道理的,因为本来0和-0在计算机中用2进制存储就应该不一样,按照我们讲的,应该是
0-> 
0000 0000 0000 0000 0000 0000 0000 0000
-0->
1000 0000 0000 0000 0000 0000 0000 0000
但是人家就是规定了0和-0我都存储为0,霸道吧。可能是想让数据两端保持个数一致吧,本来这样多好
…… -3 -2 -1 -0] [0 1 2 3 ……
但是现在中间的两个0合并了,而我们对
1000 0000 0000 0000 0000 0000 0000 0000
减1,取反以后得到
1000 0000 0000 0000 0000 0000 0000 0000
还是他本身,鉴于这种特性,就把它作为最小的int型可以表示的整数,并且规定其值为-2147483648。而且这样也可以解释下面的程序了 

public static void Main() 
{
    
int a =-2147483648
;
    
int b =2147483647
;
    a
--
;
    b
++
;
    Console.WriteLine(a);
// print:2147483647

    Console.WriteLine(b);// print:-2147483648
}

先来看a,2进制为
1000 0000 0000 0000 0000 0000 0000 0000
a-1就等于a+(-1),-1的2进制为
1111 1111 1111 1111 1111 1111 1111 1111
两者相加为
   1000 0000 0000 0000 0000 0000 0000 0000
+
1111 1111 1111 1111 1111 1111 1111 1111
------------------------------------------------------------------------------------------
 
10111 1111 1111 1111 1111 1111 1111 1111
而实际上最前面的一位1已经超出了本身int型的范围,所以一般就会被自动截取掉了,而一般的编译器也不会报错,我指的是象我那样写int a =-2147483648;a--;当然,如果你直

接int a =-2147483648-1;的话一般编译的时候就会报错的。最后得到的结果就是
0111 1111 1111 1111 1111 1111 1111 1111
成了2147483647,b可以同理计算出来。
似乎就是这么个事情。这样你也可以知道float的取值范围了。以上int型均指在32位机上的结果。

阅读(1056) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~