[初学C语言]第一个遇到的数据类型溢出问题1063:最大公约与最小公倍数

1063: 最大公约与最小公倍

时间限制: 1 Sec 内存限制: 128 MB
提交: 17697 解决: 7479

题目描述
输入两个正整数,输出其最大公约数和最小公倍数。

输入
输入两个正整数n和m(n,m<=1000000)。输入保证最终结果在int范围内。

输出
输出两个整数,用空格隔开。表示m和n的最大公约数和最小公倍数。

样例输入
4 6

样例输出
2 12

提示 注意运算过程中的溢出问题

这是一道很基础的题目,用辗转相除法算出最大公约数,然后用公式a*b/(MaxGY)算出最小公倍数即可。所以我写了如下代码:

#include <stdio.h>
int MaxGY(int m,int n){//   假设m<n
    if(m>n){
        int temp=m;
        m=n;
        n=temp;
    }
    int i=m,max=n;
    while(max%i!=0){
        i=max%i;
        if(i>max){
            int temp=i;
            i=max;
            max=temp;
        }
    }
    return i;
}
int MinGB(int m,int n){
    int mingb;
    mingb=m*n/MaxGY(m,n);
    return mingb;
}
int main()
{
    int m,n;
    scanf("%d %d",&m,&n);
    printf("%d %d",MaxGY(m,n),MinGB(m,n));
    return 0;
}

使用样例输出没有出现错误,但是提交却发生了错误:
错误提示
很明显,oj尝试1000000 1000000这组数据,发生了类型溢出。
于是我添加了如下语句:

double x=a*b;

提交后结果仍然和上图一样。
我通过查书看到double的大小为2^524503 5996 2737 0496,只有16位,而x为1 0000 0000 0000,说明错误不在double型变量x身上,而很有可能在于运算过程的数据溢出。
我把有关的数据类型全都改为double,这次没有出错,但是运行时间和内存一定会更大,一定有更好的方法。
我把求最小公倍数的公式改为

mingb=m/MaxGY(m,n)*n;

这次运算过程没有溢出,说明一直都是运算过程的锅。
这样写能成功,证明了乘法有可能溢出,但除法一定不会溢出。因此同时存在乘法和除法运算的式子里应该先写除法,避免过程溢出。
在这个问题里,这样写没有风险,但是在其他地方这样写仍有可能溢出,保险起见数据类型还是应该改为double以保证风险最小。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值