printoutevery 中 if(k=0) 是賦值而非判斷,應為 if(k < 0) 或 if(k == 0) (配合遞歸終止條件)。a 的循環邏輯錯誤:if(num < pow(i, k)) 應為 pow(i, a),且循環變量混淆。pow() 性能低且精度問題 (浮點轉整型)。
#include
#include
// 遞歸輸出每一位
void printDigit(int num, int base, int pos) {
if (pos < 0) return; // 終止條件:位數耗盡
// 計算當前位權值 base^pos (用整數避免浮點誤差)
int power = 1;
for (int i = 0; i < pos; i++) power *= base;
int digit = num / power; // 當前位數值
num -= digit * power; // 剩餘數值
// 輸出字符
if (digit < 10) putchar('0' + digit);
else putchar('A' + digit - 10); // 10->A, 15->F 等
// 遞歸下一位
printDigit(num, base, pos - 1);
}
// 計算最高位位置 (最高次方數)
int highestPosition(int num, int base) {
if (num == 0) return 0;
int pos = 0;
int value = 1;
while (value <= num / base) { // 防止溢出
value *= base;
pos++;
}
return pos;
}
int main() {
int num, base;
printf("輸入十進制整數: ");
scanf("%d", &num);
printf("輸入目標進制 (2-36): ");
scanf("%d", &base);
if (base < 2 || base > 36) {
printf("進制範圍 2-36\n");
return 1;
}
if (num < 0) {
putchar('-');
num = -num; // 注意 INT_MIN 絕對值溢出,簡化處理
}
if (num == 0) {
putchar('0');
} else {
int pos = highestPosition(num, base);
printDigit(num, base, pos);
}
putchar('\n');
return 0;
}
| 原代碼 | 修正 | 說明 |
|---|---|---|
if(k=0) | if(pos < 0) | 遞歸終止條件,防止無限遞歸 |
循環查找 a 用 pow(i, k) | 預計算 power = base^pos,用整數除法 | |
浮點 pow() 轉整型 | 整數乘法累積 power | |
| 無負數處理 | 輸出 '-' 後取絕對值 | |
| 進制限制 | 檢查 2-36 範圍 |
void printBaseIterative(int num, int base) {
if (num == 0) { putchar('0'); return; }
if (num < 0) { putchar('-'); num = -num; }
char buf[64]; // 足夠 64 位整數任意進制
int idx = 0;
while (num > 0) {
int digit = num % base;
buf[idx++] = (digit < 10) ? '0' + digit : 'A' + digit - 10;
num /= base;
}
// 逆序輸出
while (idx > 0) putchar(buf[--idx]);
}
// itoa 非標準但廣泛可用
char buf[33];
itoa(num, buf, base); // base 2-36
printf("%s\n", buf);
// sprintf 格式化 (僅 8, 10, 16 進制)
printf("%x\n", num); // 16進制
printf("%o\n", num); // 8進制
進制轉換核心:**反覆取模 (得當前位) + 除以基數 (得剩餘數)**,逆序輸出。遞歸易理解但迭代更健壯。生產代碼優先用標準庫 itoa / sprintf / C++ std::bitset / std::format (C++20)。