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 0

Sample 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>C
            printf("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

时间: 2024-10-14 09:26:57

PAT 1065 A+B and C[大数运算][溢出]的相关文章

关于大数运算

在接触计算机这么久以来,我一直被大数运算困扰,确切的说是在一些特定方面非常有受挫感,在计算机中的数据类型对数字支持的数位有限制,例如: long   long  int  a = 0; 这里的a 最多可以表示一个9位的长整型数字,要想存储超过9位的数字,最可行的方法是使用数组来存储每一位的值.所以在遇到大数运算的时候可以借用数组来完成相应的运算操作.

PAT 1065. A+B and C (64bit)

1 #include <stdio.h> 2 3 int main() { 4 long n, a, b, c; 5 long i; 6 int ga, gb, gc, r; 7 scanf("%ld", &n); 8 for (i=0; i<n; i++) { 9 scanf("%ld%ld%ld", &a, &b, &c); 10 ga = a >= 0; 11 gb = b >= 0; 12 gc

大数运算(python2)

偶然又遇到了一道大数题,据说python大数运算好屌,试了一发,果然方便- 1 a = int( raw_input() ); //注意这里是按行读入的,即每行只读一个数 2 b = int( raw_input() ); 3 print a+b; 4 print a*b; 5 print a/b; 6 print a%b;

大数运算之字符串模拟

相信大家被特别大的两个数据做运算折磨过.当两个操作数或者运算结果超过类型的表示范围后会有意想不到的错误,这时候我们的电脑还不如我们高中用过的科学计算器,这是作为一个程序员所不能忍受的.所以我们得找到其他的方式来计算.这就是我们今天要讨论的字符串模拟大数运算. 我们的运算一般使用int类型来算的,那么首先我们先复习一下各种int类型的数据表示范围: unsigned int 0-4294967295    int   -2147483648-2147483647  unsigned long 0-

HDU 4927 大数运算

模板很重要 #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define MAXN 9999 #define MAXSIZE 10 #define DLEN 4 class BigInt { private: int a[500]; //可以控制大数的位数 i

Big Number------HDOJ杭电1212(大数运算)

Problem Description As we know, Big Number is always troublesome. But it's really important in our ACM. And today, your task is to write a program to calculate A mod B. To make the problem easier, I promise that B will be smaller than 100000. Is it t

C++实现大数运算

项目背景: 大数运算,顾名思义,就是很大的数值的数进行一系列的运算. 我们知道,在数学中,数值的大小是没有上限的,但是在计算机中,由于字长的限制,计算机所能表示的范围是有限的,当我们对比较小的数进行运算时,如:1234+5678,这样的数值并没有超出计算机的表示范围,所以可以运算.但是当我们在实际的应用中进行大量的数据处理时,会发现参与运算的数往往超过计算机的基本数据类型的表示范围,比如说,在天文学上,如果一个星球距离我们为100万光年,那么我们将其化简为公里,或者是米的时候,我们会发现这是一个

lua实现大数运算

lua实现的大数运算,代码超短,目前只实现的加减乘运算 local mod = 10000 function add(a, b) t, c = 0, {} for i = 1, math.max(#a,#b) do t = t + (a[i] or 0) + (b[i] or 0) c[i], t = t%mod, math.floor(t/mod) end while t ~= 0 do c[#c + 1], t = t%mod, math.floor(t/mod) end return c

大数运算——加法

作为一个对编程没有很深研究的初学者,对于这些虽然没有任何算法的题仍然觉得很难很难,但是或许都是需要一个过渡时期吧,这是这几天的结果,很多有自己的考虑,自己的想法在里面,但是也百度查了很多,也看了很多别人写的关于这方面的. 先看一下关于大数方面的知识: bool型为布尔型,占1个字节,取值0或1. BOOL型为int型,一般认为占4个字节,取值TRUE/FALSE/ERROR. sbyte型为有符号8位整数,占1个字节,取值范围在128~127之间. bytet型为无符号16位整数,占2个字节,取