鱼C论坛

 找回密码
 立即注册
查看: 2924|回复: 2

输入一个小于等于1000的正整数n,输出其n次方的最后3位。n较大的时候容易溢出怎么办

[复制链接]
发表于 2020-2-10 13:58:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
/*从键盘任意输入一个小于等于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这些较大的数就不能输出正确答案。
问了一下学长说是什么同余定理,听不太懂。有大神教教我吗
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-2-10 14:27:33 | 显示全部楼层
本帖最后由 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

有的时候公式看不懂可以用纸笔写一下就好了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-2-10 16:41:52 | 显示全部楼层
0、题主的代码有点小问题改成这样:
  1. #include <Stdio.h>

  2. int main()
  3. {
  4.     unsigned int n, i;
  5.     int m = 1;

  6.     printf("请输入一个小于等于1000的正整数:");
  7.     scanf("%u", &n);

  8.     if (n >= 0 && n <= 1000)
  9.     {
  10.         for (i = 0; i < n; i++)
  11.         {
  12.             m *= n;
  13.             if (m > 1000)
  14.                 m %= 1000;
  15.             printf("m = %d\n", m);
  16.         }
  17.         printf("该数的%d次方的后三位是:%d", n, m);
  18.     }
  19.     else
  20.     {
  21.         printf("请输入在范围内的值!");
  22.     }
  23.     return 0;
  24. }
复制代码

就行了。
1、那么回答题主的疑惑
为什么把m = m % 1000放到for循环外就容易溢出啊...
放在for循环外输入91这些较大的数就不能输出正确答案。

①如果把m = m % 1000放到for循环外,这里当做你的意思是把它放在循环下面,
按照编译器读取代码编译的顺序,那么就会先算出n的n次方再求余。
②当n的n次方这个数据超过这个变量的坑(内存)所能容纳的大小,就会溢出,就冇正确答案。
③以上,我推测题主并不完全理解自己的这段代码,基础知识也没巩固
  建议:①再去看一遍小甲鱼的视频
②别再去问学长之类的了,他们可能只是想跟你装个13
③买本c语言教材,刷题。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-27 15:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表