输入一个小于等于1000的正整数n,输出其n次方的最后3位。n较大的时候容易溢出怎么办
/*从键盘任意输入一个小于等于1000的正整数n,输出其n次方的最后3位。*/#include<stdio.h>
int main()
{
int n, i;
long long m = 1;
printf("请输入一个小于等于1000的正整数n:");
scanf("%d", &n);
if(n > 1000)
{
printf("请输入在范围内的值!");
}
else
{
for(i = 1; i <= n; i++)
{
m *= n;
m = m % 1000;
}
printf("该数的%d次方的后三位是:%.3d", n, m);
}
return 0;
}
输入一个数,求它自身次方后的后三位,为什么把m = m % 1000放到for循环外就容易溢出啊...
放在for循环外输入91这些较大的数就不能输出正确答案。
问了一下学长说是什么同余定理,听不太懂。有大神教教我吗 本帖最后由 SHRS23 于 2020-2-10 14:31 编辑
既然你已经知道是同余定理那就去查有关同余的知识。
任何编程语言能直接处理的大数都是有上限的,一个数的N次幂很容易超出这个限制
超出这个限制程序就会出错。
对于这个题目,正常的思路就是像你说的把那条语句放在循环外,按照正常的逻辑就是
先把一个数的N次幂求出来,然后取后三位,但是这样必然会出现超出long long限制的情况
换一种思路,既然程序只要求后三位,那能不能一边计算幂,一边把高位(前面的位数)扔掉呢
比如 12345 × 12345 = 152399025 ;345 × 12345 = 809025 后三(例子中是后四位)位是一样的
这样得到的中间结果就能控制在比较小的范围。还能得到正确的答案。
参考:
https://blog.csdn.net/shiyongyang/article/details/78108895
在ACM做题目的过程中经常会遇到mod xxxxxxx... ,这是因为为了避免高精度的运
算。因为我们可以看得出在运算过程中算完再mod还是一遍算一边mod,最后得到的结
果是一样的,就是因为同余 的关系。因为同余关系只是关心余数,不用去在乎除的时候
整数的部分。所以,在整个运算过程中每一步最大都不会超过m,从而避免了高精度的
运算。
https://blog.csdn.net/qq_40833874/article/details/84696628
有的时候公式看不懂可以用纸笔写一下就好了 0、题主的代码有点小问题改成这样:
#include <Stdio.h>
int main()
{
unsigned int n, i;
int m = 1;
printf("请输入一个小于等于1000的正整数:");
scanf("%u", &n);
if (n >= 0 && n <= 1000)
{
for (i = 0; i < n; i++)
{
m *= n;
if (m > 1000)
m %= 1000;
printf("m = %d\n", m);
}
printf("该数的%d次方的后三位是:%d", n, m);
}
else
{
printf("请输入在范围内的值!");
}
return 0;
}
就行了。
1、那么回答题主的疑惑
为什么把m = m % 1000放到for循环外就容易溢出啊...
放在for循环外输入91这些较大的数就不能输出正确答案。
①如果把m = m % 1000放到for循环外,这里当做你的意思是把它放在循环下面,
按照编译器读取代码编译的顺序,那么就会先算出n的n次方再求余。
②当n的n次方这个数据超过这个变量的坑(内存)所能容纳的大小,就会溢出,就冇正确答案。
③以上,我推测题主并不完全理解自己的这段代码,基础知识也没巩固
建议:①再去看一遍小甲鱼的视频
②别再去问学长之类的了,他们可能只是想跟你装个13
③买本c语言教材,刷题。
页:
[1]