將十進制整數 `N` 轉為 `base (2~16)` 進制:
#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;
}
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');
}
浮點數無單一「進制」表示,常見需求:
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,精確無損 |
十進制轉任意進制,「除基取餘 + 逆序輸出」是不變的核心。工程上優先用 `sprintf`/`strtol` 標準函式;教學/嵌入式/無標準庫環境時,手寫版本務必處理好 `INT_MIN` 溢位、緩衝區邊界、負數符號三大細節。