qq_34174865 2016-03-17 00:36 采纳率: 50%
浏览 2181
已采纳

c语言程序设计(很难的一道题)

一、将分数变小数:写出一个程序,接受一个以N/D的形式输入的分数,其中N为分子,D为分母,输出它的小数形式。如果它的小数形式存在循环节,要将其用括号括起来。例如:1/3=.00000...表示为.(3),又如41/333=.123123123...表示为.(123)。
一些转化的例子: 1/3=.(3) 22/5=4.4 1/7=.(142857) 3/8=.375 45/46=.803(571428)
  用上面的分数和13/79来测试你的程序。求高手

  • 写回答

2条回答 默认 最新

  • cxsmarkchan 2016-03-17 07:02
    关注

    有两个关键点:
    1. 不能用float等浮点数类型,要用整数类型和高精度处理。
    2. 需要了解循环小数的产生来源于除数中有2和5以外的因子。
    以下C++代码在g++下编译通过,可以处理D<10000的情况,循环节不超过40位。我的电脑上没有C编译程序,但除了头文件包含部分,我都尽量按照C语言的格式写了,希望对你有帮助。
    不过,45/46你给的结果不正确,应该是:.9(7826086956521739130434),你可以用计算器验算一下。
    望采纳。

    #include <cstdio>
    #include <cstdlib>
    #include <string>
    #include <cstring>
    using namespace std;
    
    #define LEN 10
    #define EACH_MAX 10000
    
    //高精度取余
    int exactRemainder(int* K, int D){
        int i;
        int tmp[LEN];
        memcpy(tmp, K, sizeof(int) * LEN);
        for(i = LEN - 1; i > 0; i--){
            tmp[i] %= D;
            tmp[i - 1] += tmp[i] * EACH_MAX;
        }
        return tmp[0] % D;
    }
    
    //高精度输出循环节(99999...999/D*N)
    void printCirculator(int *K, int D, int N){
        int begin = 0;
        int i;
        int tmp[LEN];
        memcpy(tmp, K, sizeof(int) * LEN);
    
        for(i = LEN - 1; i > 0; i--){
            tmp[i - 1] += (tmp[i] % D) * EACH_MAX;
            tmp[i] /= D;
        }
        tmp[0] /= D;
    
        for(i = 0; i < LEN; i++){
            tmp[i] *= N;
        }
        for(i = 0; i < LEN - 1; i++){
            tmp[i + 1] += tmp[i] / EACH_MAX;
            tmp[i] %= EACH_MAX;
        }
    
        for(i = LEN - 1; i >= 0; i--){
            if(begin == 1){
                printf("%04d", tmp[i]);
            }else if(tmp[i] != 0){
                begin = 1;
                printf("%d", tmp[i]);
            }
        }
    }
    
    //在999..9前面再加一个9
    void next9(int *K){
        int i;
        for(i = 0; i < LEN; i++){
            K[i] *= 10;
        }
        for(i = 0; i < LEN - 1; i++){
            if(K[i] >= EACH_MAX){
                K[i + 1] += K[i] / EACH_MAX;
                K[i] %= EACH_MAX;
            }
        }
        K[0] += 9;
    }
    
    int main(){
        int N, D;
        int K[LEN];
        memset(K, 0, sizeof(int) * LEN);
        scanf("%d%d", &N, &D);
    
        //如果N比D大,则有整数部分,先输出
        if(N >= D){
            printf("%d", N / D);
        }
        N %= D;
        //小数点
        printf(".");
    
        //把D因子中的10,2,5都除去
        while(1){
            if(D % 10 == 0){
                D /= 10;
                if(N % 10 == 0){
                    N /= 10;
                }else if(N >= D){
                    printf("%d", N / D);
                    N %= D;
                }else{
                    printf("%d", 0);
                }
            }else if(D % 2 == 0){
                N *= 5;
                D *= 5;
            }else if(D % 5 == 0){
                N *= 2;
                D *= 2;
            }else{
                break;
            }
        }
        //此时N < D且D因子中不含有2和5,即纯循环部分
        if(N != 0){
            printf("(");
            next9(K);
            while(exactRemainder(K, D) != 0){
                next9(K);
            }
            printCirculator(K, D, N);
            printf(")");
        }
        printf("\n");
        return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 商城生产日期批次库存问题
  • ¥15 esp8266控制共阳极wrgb灯板无法关闭所有led灯
  • ¥100 python读取速度问题
  • ¥15 stm32f407使用DMA问题
  • ¥15 您好 这个API接口该怎么弄 网站搭建好了 API也有 现在就不知道该怎么填写API 不知道怎么用
  • ¥88 用uniapp写一个多端的程序,用到高德地图,用高德的JSAPI吗?
  • ¥20 关于#c++#的问题:水果店管理系统
  • ¥30 dbLinq最新版linq sqlite
  • ¥20 对D盘进行分盘之前没有将visual studio2022卸载掉,现在该如何下载回来
  • ¥15 完成虚拟机环境配置,还有安装kettle