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

C 語言十進制轉二進制(含小數)常見錯誤與修正

     編輯:程式設計綜合問答

原始代碼主要問題

  1. 變數 i 未初始化:導致 decimalbuffer[i] 寫入隨機位置,造成未定義行為。
  2. decimalnumber 未賦值:宣告後直接用於計算 a = decimalnumber = number - value,但 decimalnumber 本身未初始化。
  3. 小數轉換邏輯缺陷:浮點數精度誤差會導致無限循環,需設定最大位數或誤差閾值。
  4. 使用非標準 itoa:非 ANSI C 標準,移植性差。

修正版代碼 (C99 標準)

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

#define MAX_DECIMAL_BITS 16  // 小數最大位數

void intToBin(long n, char *buf) {
    if (n == 0) { strcpy(buf, "0"); return; }
    char tmp[64];
    int pos = 0;
    while (n > 0) {
        tmp[pos++] = '0' + (n & 1);
        n >>= 1;
    }
    // 反轉
    for (int i = 0; i < pos; ++i) buf[i] = tmp[pos - 1 - i];
    buf[pos] = '\0';
}

void fracToBin(double frac, char *buf, int maxBits) {
    int pos = 0;
    const double eps = 1e-10;
    while (frac > eps && pos < maxBits) {
        frac *= 2;
        int bit = (int)frac;
        buf[pos++] = '0' + bit;
        frac -= bit;
    }
    buf[pos] = '\0';
}

int main() {
    double number;
    printf("請輸入十進制數:");
    if (scanf("%lf", &number) != 1) return 1;

    long integerPart = (long)number;
    double fracPart = number - integerPart;
    if (fracPart < 0) fracPart = -fracPart; // 處理負數

    char intBin[64], fracBin[MAX_DECIMAL_BITS + 1];
    intToBin(integerPart, intBin);
    fracToBin(fracPart, fracBin, MAX_DECIMAL_BITS);

    printf("二進制:%s", intBin);
    if (strlen(fracBin) > 0) printf(".%s", fracBin);
    printf("\n");
    return 0;
}

關鍵改進點

  • 所有區域變數定義時初始化。
  • 拆分整數/小數轉換函式,職責單一。
  • 小數迴圈加入 eps 判斷,避免浮點誤差導致無限循環。
  • 移除 itoa,改用位運算手寫轉換,標準可移植。
  • 支援負數輸入(分開處理符號位)。

進階話題:IEEE 754 精確轉換

若需精確對應單/雙精度浮點數位模式,可使用 union 或 memcpy 直接讀取位元組,而非數學轉換。

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