将两个长数相乘
Posted
技术标签:
【中文标题】将两个长数相乘【英文标题】:Multiplying two long numbers 【发布时间】:2017-04-10 11:26:17 【问题描述】:我试图通过 C 程序乘以数字,即 10000
和 10000 + 1
。但我没有得到正确的输出。
printf("%lld",(100000)*(100001));
我已经在不同的编译器上尝试了上面的代码,但我得到的是相同的 1410165408
而不是 10000100000
。
【问题讨论】:
看起来你在一个平台上,int
是 32 位(或差不多,但最有可能是 32)。您需要使用更广泛的数据类型。
【参考方案1】:
好吧,让我们相乘
int64_t a = 100000;
int64_t b = 100001;
int64_t c = a * b;
我们会得到(二进制)
1001010100000011010110101010100000 /* 10000100000 decimal */
但是如果你把它转换成int32_t
int32_t d = (int32_t) c;
你只会得到最后 32 位(并且扔掉顶部的10
):
01010100000011010110101010100000 /* 1410165408 decimal */
最简单的方法可能是将两个常量声明为 64 位 值(LL
后缀代表long long
):
printf("%lld",(100000LL)*(100001LL));
【讨论】:
请注意,附加LL
将确保常量至少具有 64 位宽度,因为 long long
必须是该宽度或更宽。【参考方案2】:
在 C 中,用于计算的类型取决于 操作数 的类型,而不是存储结果的类型。
像100000
这样的普通整数常量是int
类型的,因为它们可以放在一个里面。但是,100000 * 100001
的乘法将不适合,因此会出现整数溢出和未定义的行为。切换到long
不一定能解决任何问题,因为它也可能是 32 位的。
此外,打印带有%lld
格式说明符的int
在大多数系统上也是未定义的行为。
这里万恶之源是 C 中糟糕的默认类型(出于某种原因称为“原始数据类型”)。只需摆脱它们及其所有不确定性,您的所有错误都会随之消失:
#include <stdio.h>
#include <inttypes.h>
int main(void)
printf("%"PRIu64, (uint64_t)100000 * (uint64_t)100001);
return 0;
或等效:UINT64_C(100000) * UINT64_C(100001)
。
【讨论】:
Detail;:如果代码使用UINT64_C(100000) * ...
,返回类型uint_least64_t
,那么指定匹配的printf说明符为PRIuLEAST64
【参考方案3】:
你的两个整数是int
,这也会产生int
的结果。 printf()
格式说明符说 %lld
,它需要 long long int
,这无关紧要。
您可以转换或使用后缀:
printf("%lld", 100000LL * 100001LL);
这将打印10000100000
。当然还是有限制的,因为long long int
中的位数仍然是恒定的。
【讨论】:
【参考方案4】:你可以这样做
long long int a = 100000;
long long int b = 100001;
printf("%lld",(a)*(b));
这将给出正确的答案。
您所做的是(100000)*(100001)
,即默认情况下编译器将100000
转换为整数并将100001
相乘并将其存储在(int)
但是在 printf 期间,它会将 (int) 打印为 (long long int)
【讨论】:
以上是关于将两个长数相乘的主要内容,如果未能解决你的问题,请参考以下文章