https://practice.geeksforgeeks.org/problems/abset-2/0/ ,这是一个gfg问题,我被要求输出我的数字(a^b)模数10^9+7。
这是我的第一个密码;
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t--!=0){
int a = sc.nextInt();
int b = sc.nextInt();
int result = 1;
for(int i = 0; i<b; i++){
result = result*a;
}
System.out.println(result%1000000007);
}
}
它没有给出99^928的正确输出。然后我把结果的数据类型改成了long,甚至是一个负数。然后我不得不像这样修改我的代码,它成功了
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t--!=0){
int a = sc.nextInt();
int b = sc.nextInt();
long result = 1;
for(int i = 0; i<b; i++){
result = (result*a);
result = result%1000000007;
}
System.out.println(result);
}
这里我的问题是当我把结果%100000007放在for循环中它是如何工作的,根据这个问题我不应该输出最终的结果模数10^9+7吗?
2条答案
按热度按时间7ivaypg91#
99^928是一个1852位的大数字。java中的原始数据类型int和long没有这样的存储容量:int中可以存储的最大值是2147483647,long中可以存储的最大值是9223372036854775807。返回较大值的操作环绕,返回一个正确的模2的幂,但在大多数实际用途中完全不可用的值。
如果打印出中间值,将看到结果在99^10处环绕:
99^9 = 913517247483640899
99^10 = -1795512867667309079
这意味着如果你等到最后一刻才做模运算,你将得到一个不正确的中间结果的模。必须通过在中间步骤中使用模来控制值的大小。
请注意,java确实有用于处理大于长整数的整数的类:
java.math.BigInteger
. 它甚至为您正在实施的“模块化电源”操作提供了方便快捷的方法:hsgswve42#
int
以及long
具有最大值。取决于a
以及b
a^b
超过最大值并溢出。最后的模运算将作用于错误的溢出值,结果将被关闭。
模的问题是,你可以在你的计算过程中应用模,基本上只要你想,而不改变结果。
(a + b) mod m
具有与相同的值(a mod m + b mod m) mod m
同样地(a * b) mod m
与相同(a mod m * b mod m) mod m
,这就是模运算符的工作原理。只需在纸上玩几个小的b和m值,看看规则是否有效。这是非常典型的分配涉及巨大的价值是可计算的,只有当你添加一些
mod m
在混合中的某个步骤(只要它们有意义)。