将两个长数相乘

Posted

技术标签:

【中文标题】将两个长数相乘【英文标题】:Multiplying two long numbers 【发布时间】:2017-04-10 11:26:17 【问题描述】:

我试图通过 C 程序乘以数字,即 1000010000 + 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)

【讨论】:

以上是关于将两个长数相乘的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 将两个 NSDecimal 数字相乘

用openCV将两个图像相乘

C如何将两个浮点数相乘? [关闭]

将两个数字相乘然后相加

在 C++ 中将两个矩阵相乘

如何用最少的指令将两个四元数相乘?