首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言實現十進制轉 2-16 進制通用演算法(含負數與浮點數擴充)

     編輯:關於C語言

核心演算法:除基取餘法

將十進制整數 `N` 轉為 `base (2~16)` 進制:

  1. 若 `N == 0` 直接輸出 `"0"`。
  2. 記錄符號,轉為無號正數處理。
  3. 迴圈:`digit = N % base`;`N /= base`;將 `digit` 對應字元 (`0-9A-F`) 壓入堆疊/陣列。
  4. 迴圈結束後逆序輸出字元陣列。
  5. 若原為負數,前綴 `'-'`。

完整 C99 實作(整數版)

#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#include <inttypes.h>

void print_int_base(intmax_t value, int base) {
    if (base < 2 || base > 16) { puts("Base must be 2..16"); return; }

    const char *digits = "0123456789ABCDEF";
    char buf[sizeof(intmax_t) * CHAR_BIT + 2];  // 足夠容納二進位 + 符號 + \0
    int i = 0;
    bool neg = false;

    if (value == 0) { putchar('0'); putchar('\n'); return; }
    if (value < 0) { neg = true; value = -value; }  // 注意 INTMAX_MIN 絕對值溢位,實務用 uintmax_t 處理

    while (value > 0) {
        buf[i++] = digits[value % base];
        value /= base;
    }
    if (neg) buf[i++] = '-';
    while (i--) putchar(buf[i]);
    putchar('\n');
}

int main(void) {
    print_int_base(255, 16);   // FF
    print_int_base(-42, 2);    // -101010
    print_int_base(0, 8);      // 0
    return 0;
}

進階:支援 `INTMAX_MIN` 絕對值溢位

void print_int_base_safe(intmax_t value, int base) {
    if (base < 2 || base > 16) return;
    const char *digits = "0123456789ABCDEF";
    char buf[sizeof(intmax_t) * CHAR_BIT + 2];
    int i = 0;
    uintmax_t uval;

    if (value < 0) {
        uval = (uintmax_t)(- (value + 1)) + 1;  // 避免 -INTMAX_MIN 溢位
        buf[i++] = '-';
    } else {
        uval = (uintmax_t)value;
    }
    if (uval == 0) { putchar('0'); putchar('\n'); return; }
    while (uval) {
        buf[i++] = digits[uval % base];
        uval /= base;
    }
    if (buf[0] == '-') {  // 負號已在最前,需將數字部分逆序
        for (int j = i-1; j >= 1; --j) putchar(buf[j]);
        putchar('-');
    } else {
        while (i--) putchar(buf[i]);
    }
    putchar('\n');
}

浮點數轉換:IEEE 754 位元級輸出

浮點數無單一「進制」表示,常見需求:

  • 十六進位位元模式:`printf("%a", f)` (C99 `%a` 輸出 `0x1.8p+3` 科學記號) 或手動解析 `sign/exponent/mantissa`。
  • 自訂基數小數點表示:整數部份用除基法,小數部份用「乘基取整法」:
void print_frac_base(double val, int base, int precision) {
    if (val < 0) { putchar('-'); val = -val; }
    uintmax_t ipart = (uintmax_t)val;
    double fpart = val - ipart;
    print_int_base_safe(ipart, base);  // 整數部份
    putchar('.');
    for (int i = 0; i < precision && fpart > 0; ++i) {
        fpart *= base;
        int digit = (int)fpart;
        putchar("0123456789ABCDEF"[digit]);
        fpart -= digit;
    }
    putchar('\n');
}

標準庫替代方案

需求標準函式說明
整數轉 8/10/16 進位字串`sprintf(buf, "%o/%d/%x", val)`標準、安全、支援寬度/精度/旗標
任意基數 (2~36) 字串轉整數`strtol(str, NULL, base)`反向轉換首選
浮點數十六進位科學記號`printf("%a", f)` / `%A`C99,精確無損

常見坑點總結

  1. 緩衝區大小:`intmax_t` 二進位最多 64 位 + 符號 + `\0` → 66 bytes,陣列務必足夠。
  2. 負數最小值:`-INTMAX_MIN` 無法用有號型別表示,必須轉 `uintmax_t` 處理。
  3. 基數驗證:`base < 2 || base > 36` (字母表長度) 直接報錯。
  4. 浮點數精度:乘基取整法會累積誤差,僅適合顯示用途,不可用於金融/科學計算。

十進制轉任意進制,「除基取餘 + 逆序輸出」是不變的核心。工程上優先用 `sprintf`/`strtol` 標準函式;教學/嵌入式/無標準庫環境時,手寫版本務必處理好 `INT_MIN` 溢位、緩衝區邊界、負數符號三大細節。

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