Evo. G Tech Team Forum
Welcome to Evo. G Tech Team Forum. We have moved to a new website : www.evogtechteam.com

Thanks you.

by Evo. G Tech Team Management.

Join the forum, it's quick and easy

Evo. G Tech Team Forum
Welcome to Evo. G Tech Team Forum. We have moved to a new website : www.evogtechteam.com

Thanks you.

by Evo. G Tech Team Management.
Evo. G Tech Team Forum
Would you like to react to this message? Create an account in a few clicks or log in to continue.

4294967295 + 4294967295 = 4294967294?

Go down

4294967295 + 4294967295 = 4294967294? Empty 4294967295 + 4294967295 = 4294967294?

Post by too wei December 9th 2015, 14:06

什么?
4294967295 + 4294967295 = 4294967294?
不是 8589934590吗?

到底答案是4294967294还是859934590呢?为了了解
1.首先,先拿起一支笔和纸
2.慢慢的写下你的算式
3.你会得到答案是8589934590
4.为了节省时间,你可以使用计算机 Very Happy 

那么你再运行一次下面的代码

Code:
int main()
{
 unsigned m = 0xFFFFFFFF; //0xFFFFFFFF是16进制,换去10进制是4294967295
 unsigned n = 0xFFFFFFFF;
 unsigned result = m+n;

 cout<<m<<" + "<<n<<" = "<<result<<endl;

 return 0;
}

运行结果
4294967295 + 4294967295 = 4294967294

什么!为什么答案会是4294967294,而不是刚刚所算到的8589934590?
原因就是溢出!也就是overflow!

什么溢出?
溢出就是计算机已经不能准确表示我们所算出来的结果(简单说就是计算机到了极限)
如果计算结果的数据长度比计算机的字多的话,那就需要截断(下面会解释),一旦截断了,那么我们所算到的的真实结果就会发生变动,这种情况叫做溢出

无符号数(unsigned)加法时的溢出overflow
为了明白上面所发现的"世界奇观",先明白一点关于16进制和2进制之间的转换

16进制转换到2进制
PS:16进制常常以0x开头

16进制    2进制
0           0000
1           0001
2           0010
3           0011
4           0100
5           0101
6           0110
7           0111
8           1000
9           1001
A           1010
B           1011
C           1100
D           1101
E           1110
F           1111

上面的意思就是在16进制里的F换去二进制就是1111

看看例子就明白了
0x3E换去二进制就是0011 1110
0xBD换取二进制就是1011 1101

2进制去16进制
也是使用同样的方法
0100 0011 换去16进制就是0x43
1110 1011 换取16进制就是0xEB


回到代码中,
unsigned m = 0xFFFFFFFF;
unsigned n = 0xFFFFFFFF;
m和n进行了加法,为了简单我们先把他换成二进制,再进行加法运算(算法和十进制类似)
1111 1111 1111 1111 1111 1111 1111 1111
+ 1111 1111 1111 1111 1111 1111 1111 1111
------------------------------------------

1 1111 1111 1111 1111 1111 1111 1111 1110


这里他的位多了一个出来,在2进制的加法中,答案出来的位数必须和原本的一样,所以这里,我们就必须截断,也就是把多出来的1拿走
拿走多出来的1后,就会变成
1111 1111 1111 1111 1111 1111 1111 1110

现在,我们再换回去16进制(或者要跳过16进制,直接去10进制也行,这里换16进制只是要表示值已经变了)
FFFFFFFE
很容易的看得出,值已经变了
但是要得到代码中出现的结果还要换去10进制才看得明白


16进制去10进制有个很简单的方法
F在10进制里是15
E在10进制里是14


F F F F F F F E

16^7 16^6 16^5 16^4 16^3 16^2 16^1 16^0


15(16^7)+15(16^6)+15(16^5)+15(16^4)+15(16^3)+15(16^2)+15(16^1)+14(16^0) = 4294967294



所以我们证实了4294967295 + 4294967295 = 4294967294(对计算机来说)


但对人类来说还是4294967295 + 4294967295 = 8589934590哦

too wei
Sponsor
Sponsor

Posts : 31
Points : 69411
Reputation : 0
Join date : 2015-04-21
Age : 26
Location : Johor

Back to top Go down

Back to top


 
Permissions in this forum:
You cannot reply to topics in this forum