【愿成其身】[6]A×B的学问 – 较大数的处理

本篇文章讲解题目:愿成其身A×B

推荐先独立进行解题尝试,然后再阅读本篇讲解!


对于这一题,因为C语言中用"*“号来表示乘法,所以我们很容易写出以下代码。

1
2
3
4
5
6
7
#include<stdio.h>
int main() {
    int A,B;
    scanf("%d %d",&A,&B);
    printf("%d\n",A*B);
    return 0;
}

提交发现wrong answer答案错误。

分析题目数据范围:$-10^9<a,b<10^9$。

我们知道int类型在电脑中的范围是$-2^{32}\leq int \leq2^{32}-1$。

大概约为2147483648~2147483647(PS:可以自己想办法求求看哦~)

而很显然a,b是在int范围内的,那么为什么会出现答案错误呢……


计算A×B的范围是$-10^{18}<a,b<10^{18}$。

超出了int范围了!

我们可以试着输入测试数据:

100000000 100000000

上述程序输出了错误答案……


怎么解决呢?

有一种比int类型范围更大的数据类型long long(__int64)类型。

写成两种形式是因为C语言的标准不同,导致不同的编译器版本可能有不一样的规定,具体使用哪一种类型,需要查看OJ的FAQ,一般都会特别说明(此题所使用的OJ采取long long)。


long long的范围大概为$-2^{64}\leq long long \leq 2^{64}-1$。

使用时与int类似,声明写为:

1
long long a;

代表声明一个名称为a的long long型变量。

在格式化输入输出函数里,正如%d代表int型,我们用%lld代表long long型(%I64d代表__int64型)。

所以此题即可使用long long解决。


因为若非必要,应该优先使用int型,所以若感觉此题可用int读取a,b,则也可进行解题。

但输出时需要注意!

如果写作

1
printf("%lld\n",a*b);

测试发现依旧会出现错误,因为编译器计算时,a与b都是int型,则a*b就会以int型计算,这样写只不过是把这个int型以long long型输出。

而实际上,在a*b时就已经超过int型了,所以会出现错误答案,这就属于中间结果溢出。


那么应该怎么写呢?

我们可以使用类型转换写为:

1
printf("%lld\n",(long long)a*b);

此语句表示把a转换为long long类型,然后与b进行乘法运算,并且结果以long long型输出。

long long型与int相乘,会把int型先转换为long long型,然后变成两个long long型相乘,从而得到正确结果。

该内容采用 CC BY-NC-SA 4.0 许可协议。

如果对您有帮助或存在意见建议,欢迎在下方评论交流。

最后更新于 2016-08-20 16:00:01

加载中...