PAT 1065 A+B and C[大数运算][溢出]
1065?A+B and C (64bit)(20?分)
Given three integers?A,?B?and?C?in [?2?63??,2?63??], you are supposed to tell whether?A+B>C.
Input Specification:
The first line of the input gives the positive number of test cases,?T?(≤10). Then?T?test cases follow, each consists of a single line containing three integers?A,?B?and?C, separated by single spaces.
Output Specification:
For each test case, output in one line?Case #X: true?if?A+B>C, or?Case #X: false?otherwise, where?X?is the case number (starting from 1).
Sample Input:
3 1 2 3 2 3 4 9223372036854775807 -9223372036854775808 0Sample Output:
Case #1: false Case #2: true Case #3: false?題目大意:給出三個數,判斷前兩個數的和是否>第三個數,數是非常大的,需要用字符串來處理的。
?//這里需要認真學習大數加法與大數乘法的套路。
//看了題解之后,才發現根本不是,long long就是2^64!!!
//這個為溢出問題,
代碼來自:https://www.liuchuo.net/archives/2023
#include <cstdio> using namespace std; int main() {int n;scanf("%d", &n);for(int i = 0; i < n; i++) {long long a, b, c;scanf("%lld %lld %lld", &a, &b, &c);long long sum = a + b;if(a > 0 && b > 0 && sum < 0) {//此時產生溢出,A+B>Cprintf("Case #%d: true\n", i + 1);} else if(a < 0 && b < 0 && sum >= 0){//產生溢出,說明64位表示不了這么小的數,printf("Case #%d: false\n", i + 1);//那么一定是小于。} else if(sum > c) {//其他為正常情況printf("Case #%d: true\n", i + 1);} else {printf("Case #%d: false\n", i + 1);}}return 0; }?
//我發現我很不理解,這個表示范圍的問題,所以學習了一下:https://blog.csdn.net/y12345678904/article/details/52854230#commentBox
對于int 來說,4個字節,32位,有一位是符號為,那么它表示的數的范圍就是(-2^31,2^31-1)。
右邊的很好理解,比如4位,除去一位符號位,最大正數能表示7,(2^3-1).
那么對于最小數呢?由于負數在計算機中是用補碼(原碼取反+1)來存的,
-1的原碼:1000 0000 0000 0000 0000 0000 0000 0001;
-1的補碼:1111 1111 1111 1111 1111 1111 1111 1111;
-2147483647(-2^31+1)原碼:1111 1111 1111 1111 1111 1111 1111 1111;
-2147483647補碼:1000 0000 0000 0000 0000 0000 0000 0001;
但是!零有二進制中+0和-0兩種形式:
+0原碼為:0000 0000 0000 0000 0000 0000 0000 0000;
-0原碼為:1000 0000 0000 0000 0000 0000 0000 0000;
那么就將-0拿來作為了-2^31,所以就是這么來的!
-2147483648的補碼表示為1000 0000 0000 0000 0000 0000 0000 0000,在32位沒有原碼。
注意,這個補碼并不是真正的補碼,真正的補碼(原碼也是這個)是1 1000 0000 0000 0000 0000 0000 0000 0000,溢出(已經多了一位1,!不是32位能表示的了!)。
溢出情況:https://blog.csdn.net/diffjd/article/details/72835698
比如1字節為例:
正數區間:0000 0001 ~ 0111 1111? (1~127)
負數區間:1000 0000 ~ 1111 1111(-1~-127)
并且規定將-0表示為-128,那么如果最大整數超過產生溢出怎么辦?
寫了一個:
對圖中a的二進制:0111 1111 1111 1111,此時再加就會超出界限,1000 0000 0000 0000,此時就是溢出了,就變為了負數,
此時:-32768在計算機中的表示就是-0,也就是1000 0000 0000 0000,那么在此基礎上再做++運算,在計算機中補碼是直接進行加法運算的,
結果就是1000 0000 0000 0001(對應的原碼是:1111 1111 1111 1111),對應的十進制就是-32767.
?終于搞明白了!
如圖中的最后一行三個數:
其中2表示-32767中有兩個1,包括符號位1和最后一位1;
其中1表示-32768中有一個1,即符號為的1;
其中16表示-1中有16個1,全為1.
這個運行結果再一次的證明了,會變成整數,是直接進行補碼運算的。
//終于搞明白了!?
轉載于:https://www.cnblogs.com/BlueBlueSea/p/9531764.html
總結
以上是生活随笔為你收集整理的PAT 1065 A+B and C[大数运算][溢出]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【前端面试】数据类型与类型检测
- 下一篇: 【Maven】CentOS7使用Nexu