C++进制转换全攻略——目录
C++进制转换全攻略
在编程中,进制转换是一个常见且重要的操作。C++提供了多种方法来实现不同进制之间的转换,无论是将十进制数转换为二进制、八进制或十六进制,还是将其他进制的数转换为十进制,都可以通过内置函数或自定义算法来实现。本文将详细介绍C++中的进制转换方法,包括基本原理、常用函数以及实际应用示例。
一、进制转换的基本原理
进制转换的核心思想是短除法和乘法加权法:
-
从十进制转换为其他进制:
不断用目标进制去除十进制数,记录余数,直到商为 0 0 0。将余数逆序排列,即为转换后的结果。 -
从其他进制转换为十进制:
将每一位的数字乘以该位对应的权重(即进制的幂),然后求和得到十进制数。
例如:
- 十进制转二进制: 45 → 101101 45 \to 101101 45→101101
- 二进制转十进制: 101101 → 45 101101 \to 45 101101→45
二、C++中常用的进制转换方法
1. 使用内置函数和流进行转换
(1) 将十进制转换为其他进制
-
std::bitset
:快速将整数转换为二进制字符串。#include <bitset> int num = 42; std::bitset<8> binary(num); // 二进制:101010 std::cout << binary << std::endl;
-
std::ostringstream
:结合std::setbase
,将整数转换为任意进制( 2 2 2、 8 8 8、 16 16 16)。#include <sstream> #include <iomanip> int num = 42; std::ostringstream oss; // 转换为二进制 oss << std::setbase(2) << num; std::cout << "Binary: " << oss.str() << std::endl; // 输出:101010 // 转换为八进制 oss.str(""); // 清空流 oss << std::setbase(8) << num; std::cout << "Octal: " << oss.str() << std::endl; // 输出:52 // 转换为十六进制 oss.str(""); oss << std::setbase(16) << num; std::cout << "Hex: " << oss.str() << std::endl; // 输出:2A
(2) 将其他进制转换为十进制
-
std::stoi
:将字符串从指定进制转换为十进制。#include <string> std::string binary = "101010"; std::string octal = "52"; std::string hex = "2A"; int dec1 = std::stoi(binary, nullptr, 2); // 二进制转十进制:42 int dec2 = std::stoi(octal, nullptr, 8); // 八进制转十进制:42 int dec3 = std::stoi(hex, nullptr, 16); // 十六进制转十进制:42 std::cout << "Decimal: " << dec1 << ", " << dec2 << ", " << dec3 << std::endl;
2. 手动实现进制转换
(1) 十进制转任意进制
通过循环和取模运算,将十进制数转换为任意进制( 2 − 36 2-36 2−36)。
#include <string>
#include <algorithm>
std::string decimalToBase(int num, int base) {
if (num == 0) return "0";
std::string result;
while (num > 0) {
int remainder = num % base;
char digit = (remainder < 10) ? ('0' + remainder) : ('A' + remainder - 10);
result.push_back(digit);
num /= base;
}
std::reverse(result.begin(), result.end());
return result;
}
int main() {
int num = 42;
std::cout << "Binary: " << decimalToBase(num, 2) << std::endl; // 输出:101010
std::cout << "Octal: " << decimalToBase(num, 8) << std::endl; // 输出:52
std::cout << "Hex: " << decimalToBase(num, 16) << std::endl; // 输出:2A
return 0;
}
(2) 任意进制转十进制
通过循环和幂运算,将其他进制的字符串转换为十进制。
#include <string>
#include <cmath>
int baseToDecimal(const std::string& num, int base) {
int decimal = 0;
for (size_t i = 0; i < num.length(); i++) {
char c = num[i];
int digit = (c >= '0' && c <= '9') ? (c - '0') : (c - 'A' + 10);
decimal = decimal * base + digit;
}
return decimal;
}
int main() {
std::string binary = "101010";
std::string octal = "52";
std::string hex = "2A";
std::cout << "Binary to Decimal: " << baseToDecimal(binary, 2) << std::endl; // 输出:42
std::cout << "Octal to Decimal: " << baseToDecimal(octal, 8) << std::endl; // 输出:42
std::cout << "Hex to Decimal: " << baseToDecimal(hex, 16) << std::endl; // 输出:42
return 0;
}
(3) 任意进制之间的转换
通过十进制作为中间桥梁,实现任意进制之间的转换。
#include <string>
#include <algorithm>
#include <cmath>
std::string decimalToBase(int num, int base) {
if (num == 0) return "0";
std::string result;
while (num > 0) {
int remainder = num % base;
char digit = (remainder < 10) ? ('0' + remainder) : ('A' + remainder - 10);
result.push_back(digit);
num /= base;
}
std::reverse(result.begin(), result.end());
return result;
}
int baseToDecimal(const std::string& num, int base) {
int decimal = 0;
for (size_t i = 0; i < num.length(); i++) {
char c = num[i];
int digit = (c >= '0' && c <= '9') ? (c - '0') : (c - 'A' + 10);
decimal = decimal * base + digit;
}
return decimal;
}
std::string convertBase(const std::string& num, int fromBase, int toBase) {
int decimal = baseToDecimal(num, fromBase);
return decimalToBase(decimal, toBase);
}
int main() {
std::string binary = "101010";
std::string hex = convertBase(binary, 2, 16); // 输出:2A
std::cout << "Converted: " << hex << std::endl;
return 0;
}
3. 处理负数和小数
上述方法主要针对正整数。如果需要处理负数或小数,可以扩展算法:
- 负数:先转换绝对值,最后添加负号。
- 小数:对整数部分和小数部分分别处理,小数部分通过乘法取整法实现。
三、实际应用示例
1. 将用户输入的二进制数转换为十六进制
#include <iostream>
#include <string>
std::string binaryToHex(const std::string& binary) {
int decimal = baseToDecimal(binary, 2);
return decimalToBase(decimal, 16);
}
int main() {
std::string binary;
std::cout << "Enter a binary number: ";
std::cin >> binary;
std::string hex = binaryToHex(binary);
std::cout << "Hexadecimal: " << hex << std::endl;
return 0;
}
2. 实现一个通用的进制转换工具(支持 2 − 36 2-36 2−36进制)
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
// 将字符转换为数值(支持2-36进制)
int charToValue(char c) {
if (c >= '0' && c <= '9') return c - '0';
else if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
else if (c >= 'a' && c <= 'z') return c - 'a' + 10;
else throw std::invalid_argument("Invalid character in input string.");
}
// 将数值转换为字符(支持2-36进制)
char valueToChar(int value) {
if (value < 10) return '0' + value;
else return 'A' + (value - 10);
}
// 将任意进制转换为十进制
long long baseToDecimal(const std::string& num, int base) {
long long decimal = 0;
for (char c : num) {
decimal = decimal * base + charToValue(c);
}
return decimal;
}
// 将十进制转换为任意进制
std::string decimalToBase(long long num, int base) {
if (num == 0) return "0";
std::string result;
while (num > 0) {
int remainder = num % base;
result.push_back(valueToChar(remainder));
num /= base;
}
std::reverse(result.begin(), result.end());
return result;
}
// 任意进制之间的转换
std::string convertBase(const std::string& num, int fromBase, int toBase) {
long long decimal = baseToDecimal(num, fromBase);
return decimalToBase(decimal, toBase);
}
int main() {
std::string num;
int fromBase, toBase;
std::cout << "Enter the number: ";
std::cin >> num;
std::cout << "Enter the from base (2-36): ";
std::cin >> fromBase;
std::cout << "Enter the to base (2-36): ";
std::cin >> toBase;
try {
std::string result = convertBase(num, fromBase, toBase);
std::cout << "Converted number: " << result << std::endl;
} catch (const std::invalid_argument& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
四、总结与注意事项
-
选择合适的方法:
- 如果只是简单转换,优先使用
std::bitset
或std::ostringstream
。 - 如果需要更灵活的功能(如处理小数或负数),建议手动实现算法。
- 如果只是简单转换,优先使用
-
注意进制范围:
std::stoi
和自定义函数通常支持 2 − 36 2-36 2−36进制。- 超出范围的进制需要额外处理。
-
处理异常情况:
- 检查输入字符串是否合法(如包含无效字符)。
- 处理负数和零的特殊情况。
-
性能优化:
- 对于大量数据或高频调用,可以考虑优化算法(如快速幂、预计算权重等)。
通过掌握C++中的进制转换方法,你可以轻松应对各种编程场景,如数据处理、网络通信、密码学等。希望本文能帮助你更好地理解和应用进制转换技术!