如何在 c 中获取 (3623752876 * 3623752876) % 4294434817
how to get (3623752876 * 3623752876) % 4294434817 in c
我实现了一个快速功率算法来执行操作 (x^y) % m
。
由于m
很大(4294434817
),我用long long
来存储结果。但是,long long
在运行过程中似乎还是不够用。例如,(3623752876 * 3623752876) % 4294434817
.
得到一个负数
有办法解决吗?
所有这三个常量都在 231 和 232.
之间
类型unsigned long long
保证能够存储至少264-1的值,超过乘积3623752876 * 3623752876
。
所以只用unsigned long long
来计算。 long long
足够宽以容纳单个常量,但不能容纳乘积。
您也可以使用 uint64_t
,在 <stdint.h>
中定义。与 unsigned long long
不同,它保证 正好 64 位宽。由于您实际上并不需要 64 位的精确宽度(128 位算术也可以),因此 uint_least64_t
或 uint_fast64_t
可能更合适。但是 unsigned long long
可以说更简单,在这种情况下它会正常工作。 (uint64_t
不保证存在,但在任何 C99 或更高版本的实现中它几乎肯定会存在。)
对于较大的值(包括中间结果),您可能需要使用比 unsigned long long
更宽的值,这可能需要某种多精度算法。 GNU GMP 库是一种可能性。另一种是使用内置支持任意宽度整数运算的语言(例如 Python)。
这个答案是基于计算(x * x) % y
虽然问题并不完全清楚。
使用 uint64_t
因为尽管 unsigned int
足够大以容纳操作数和结果,但它不会容纳乘积。
#include <stdio.h>
#include <stdint.h>
int main(void)
{
unsigned x = 3623752876;
unsigned m = 4294434817;
uint64_t r;
r = ((uint64_t)x * x) % m;
printf("%u\n", (unsigned)r);
return 0;
}
程序输出:
3896043471
我们可以利用模运算的力量来做这样的计算。两个数 a 和 b 的模数运算中乘法的基本 属性 状态:
(a*b)%m = ((a%m)*(b%m))%m
如果m适合long long int类型,那么上面的计算永远不会溢出。
由于您正在尝试进行模幂运算,因此您可以阅读更多相关信息 here。
我实现了一个快速功率算法来执行操作 (x^y) % m
。
由于m
很大(4294434817
),我用long long
来存储结果。但是,long long
在运行过程中似乎还是不够用。例如,(3623752876 * 3623752876) % 4294434817
.
有办法解决吗?
所有这三个常量都在 231 和 232.
之间类型unsigned long long
保证能够存储至少264-1的值,超过乘积3623752876 * 3623752876
。
所以只用unsigned long long
来计算。 long long
足够宽以容纳单个常量,但不能容纳乘积。
您也可以使用 uint64_t
,在 <stdint.h>
中定义。与 unsigned long long
不同,它保证 正好 64 位宽。由于您实际上并不需要 64 位的精确宽度(128 位算术也可以),因此 uint_least64_t
或 uint_fast64_t
可能更合适。但是 unsigned long long
可以说更简单,在这种情况下它会正常工作。 (uint64_t
不保证存在,但在任何 C99 或更高版本的实现中它几乎肯定会存在。)
对于较大的值(包括中间结果),您可能需要使用比 unsigned long long
更宽的值,这可能需要某种多精度算法。 GNU GMP 库是一种可能性。另一种是使用内置支持任意宽度整数运算的语言(例如 Python)。
这个答案是基于计算(x * x) % y
虽然问题并不完全清楚。
使用 uint64_t
因为尽管 unsigned int
足够大以容纳操作数和结果,但它不会容纳乘积。
#include <stdio.h>
#include <stdint.h>
int main(void)
{
unsigned x = 3623752876;
unsigned m = 4294434817;
uint64_t r;
r = ((uint64_t)x * x) % m;
printf("%u\n", (unsigned)r);
return 0;
}
程序输出:
3896043471
我们可以利用模运算的力量来做这样的计算。两个数 a 和 b 的模数运算中乘法的基本 属性 状态:
(a*b)%m = ((a%m)*(b%m))%m
如果m适合long long int类型,那么上面的计算永远不会溢出。 由于您正在尝试进行模幂运算,因此您可以阅读更多相关信息 here。