程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程解疑 >> 難題求解答-c語言程序設計(很難的一道題)

難題求解答-c語言程序設計(很難的一道題)

編輯:編程解疑
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來測試你的程序。求高手

最佳回答:


有兩個關鍵點:
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. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved