首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C語言編程練習:精確控制輸出小數位數的分數轉小數算法實現

     編輯:程式設計疑難解答

題目要求

輸入正整數 `a, b, c`,輸出 `a/b` 的小數形式,精確到小數點後 `c` 位。`a,b ≤ 10⁶, c ≤ 100`。多組數據,`0 0 0` 結束。

樣例:`1 6 4` → `Case 1: 0.1667`

核心難點

  • C 標準庫 `printf("%.c", ...)` 無法直接用變量控制精度(需 `printf("%.*f", c, val)` 但 `double` 精度不足 100 位)。
  • 大整數除法需模擬手算長除法,逐位產出小數。

高精度長除法算法 (字符串/數組模擬)

核心邏輯

  1. 整數部分:`a / b` 直接得出。
  2. 餘數 `r = a % b`。
  3. 循環 `c` 次:
    1. `r *= 10`
    2. 當前小數位 `d = r / b`
    3. 輸出/存儲 `d`
    4. `r = r % b`
    5. 若 `r == 0` 可提前結束(有限小數),後續補 0。

完整代碼 (C99 標準)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_C 105

int main() {
    long long a, b;
    int c, kase = 0;
    char decimal[MAX_C]; // 存儲小數部分字符

    while (scanf("%lld %lld %d", &a, &b, &c) == 3) {
        if (a == 0 && b == 0 && c == 0) break;

        printf("Case %d: ", ++kase);

        // 1. 整數部分
        long long integerPart = a / b;
        printf("%lld", integerPart);

        // 2. 小數部分
        if (c > 0) {
            printf(".");
            long long remainder = a % b;
            for (int i = 0; i < c; ++i) {
                remainder *= 10;
                int digit = remainder / b;
                printf("%d", digit);
                remainder %= b;
                // 可選優化:remainder==0 後 break 並補 0
            }
        }
        printf("\n");
    }
    return 0;
}

關鍵點解析

點說明
類型選擇`a,b` 用 `long long` (64位) 存儲 ≤10⁶,`remainder*10` 最大 10⁷,遠小於 2⁶³,無溢出風險
精度控制循環 `c` 次直接輸出字符,避開 `double` 精度陷阱
四捨五入題目要求「精確到」,通常指截斷。若需四捨五入,需多算一位判斷
輸出格式`Case k: ` 格式嚴格匹配,無多餘空格

進階:大整數除法 (c > 18 位超出 long long)

若 `c` 極大或 `a,b` 極大,需用字符串/數組模擬:

// 高精度除法框架
void divide(char* dividend, int divisor, int precision, char* result) {
    int len = strlen(dividend);
    int remainder = 0;
    int pos = 0;
    // 整數部分
    for (int i = 0; i < len; ++i) {
        remainder = remainder * 10 + (dividend[i] - '0');
        if (pos > 0 || remainder >= divisor) {
            result[pos++] = remainder / divisor + '0';
        }
        remainder %= divisor;
    }
    if (pos == 0) result[pos++] = '0';
    // 小數部分
    if (precision > 0) {
        result[pos++] = '.';
        for (int i = 0; i < precision; ++i) {
            remainder *= 10;
            result[pos++] = remainder / divisor + '0';
            remainder %= divisor;
        }
    }
    result[pos] = '\0';
}

總結

分數轉小數指定位數,本質是模擬手算長除法。C 語言利用 `long long` 餘數循環乘 10 除,即可輕鬆解決 100 位以內精度問題,無需引入高精度庫。關鍵在於整數與小數部分分離處理、餘數迭代、格式化輸出三步走。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved