当前位置: 首页 > news >正文

深入理解计算机进制:从原理到 C++ 实现

目录

前言

一、各进制的核心作用

1. 二进制(Binary, Base-2)

2. 八进制(Octal, Base-8)

3. 十进制(Decimal, Base-10)

4. 十六进制(Hexadecimal, Base-16)

二、进制转换的数学原理

1、十进制 ↔ 二进制转换

1. 十进制 → 二进制

2. 二进制 → 十进制

2、十进制 ↔ 八进制转换

1. 十进制 → 八进制

2. 八进制 → 十进制

3、十进制 ↔ 十六进制转换

1. 十进制 → 十六进制

2. 十六进制 → 十进制

4、二进制 ↔ 八进制转换

1. 二进制 → 八进制

2. 八进制 → 二进制

5、二进制 ↔ 十六进制转换

1. 二进制 → 十六进制

2. 十六进制 → 二进制

6、快速转换技巧

7、常见进制对照表

三、C++ 实现进制转换

四、代码解析与关键点

五、应用场景与注意事项

1. 实际应用

2. 注意事项


前言

  在计算机科学领域,进制是数据表示的基础。无论是底层的二进制电路,还是高级编程语言中的数值运算,都离不开进制的概念,本人在日常学习过程中总是对计算机进制的互相转换有点不清楚,今天借助ai以及自己学过的内容进行一个疑问的解答,帮助自己也帮助大家对各进制有什么应用场景以及它们之间相互转换的规则进行梳理

一、各进制的核心作用

1. 二进制(Binary, Base-2)

  • 作用:计算机硬件的基础语言,所有数据在内存和处理器中以二进制形式存储和处理。
  • 特点
    • 仅包含两个数字:0 和 1。
    • 每一位称为一个比特(bit),8 位组成一个字节(Byte)
  • 应用场景
    • 底层编程(如位运算、嵌入式系统)。
    • 网络协议(如 IP 地址、MAC 地址)。

2. 八进制(Octal, Base-8)

  • 作用:早期用于简化二进制表示,每 3 位二进制对应 1 位八进制。
  • 特点
    • 使用数字 0-7。
    • 前缀为0(如0377表示十进制 255)。
  • 应用场景
    • Unix/Linux 系统的文件权限(如755表示读写执行权限)。
    • 早期计算机系统(如 PDP-11)。

3. 十进制(Decimal, Base-10)

  • 作用:人类日常使用的进制,符合直觉的数值表示。
  • 特点
    • 使用数字 0-9。
  • 应用场景
    • 日常计算、财务系统。
    • 高级编程语言的默认数值输入 / 输出。

4. 十六进制(Hexadecimal, Base-16)

  • 作用:现代计算机中最常用的二进制简化表示,每 4 位二进制对应 1 位十六进制。
  • 特点
    • 使用数字 0-9 和字母 A-F(或 a-f)表示 10-15。
    • 前缀为0x(如0xFF表示十进制 255)。
  • 应用场景
    • 内存地址(如0x7FFFFFFF)。
    • 颜色编码(如#FF0000表示红色)。
    • 加密算法(如 MD5、SHA-256 哈希值)。
    • 在进程等待时从status中取得终止信号和退出状态以及是否core dump

              通过status&0x7F(也就是二进制下7个比特位为1:0000 0000 0111 1111)来取得status的前7位也就是把该进程的终止是信号拿到了,通过status右移8位再&0xFF(也就是二进制下8个比特位为1:0000 0000 1111 1111)这样就取得了status次低8位,也就是退出状态,通过status右移7位,再&0x1(0000 0000 0000 0001),这样就能取得在status下第7位的是否core dump标志了

二、进制转换的数学原理

1、十进制 ↔ 二进制转换

1. 十进制 → 二进制

方法:不断除以 2,记录余数,直到商为 0,然后反向排列余数。

示例:将十进制数 25 转换为二进制

  • 25 ÷ 2 = 12 余 1
  • 12 ÷ 2 = 6 余 0
  • 6 ÷ 2 = 3 余 0
  • 3 ÷ 2 = 1 余 1
  • 1 ÷ 2 = 0 余 1
  • 反向排列余数11001
  • 验证:2⁴ + 2³ + 0 + 0 + 2⁰ = 16 + 8 + 1 = 25

2. 二进制 → 十进制

方法:按位加权求和,权重为 2 的幂次(从右到左递增)。

示例:将二进制数 10110 转换为十进制

  • 1×2⁴ + 0×2³ + 1×2² + 1×2¹ + 0×2⁰
  • 16 + 0 + 4 + 2 + 0 = 22

2、十进制 ↔ 八进制转换

1. 十进制 → 八进制

方法:不断除以 8,记录余数,直到商为 0,然后反向排列余数。

示例:将十进制数 53 转换为八进制

  • 53 ÷ 8 = 6 余 5
  • 6 ÷ 8 = 0 余 6
  • 反向排列余数65
  • 验证:6×8¹ + 5×8⁰ = 48 + 5 = 53

2. 八进制 → 十进制

方法:按位加权求和,权重为 8 的幂次(从右到左递增)。

示例:将八进制数 247 转换为十进制

  • 2×8² + 4×8¹ + 7×8⁰
  • 128 + 32 + 7 = 167

3、十进制 ↔ 十六进制转换

1. 十进制 → 十六进制

方法:不断除以 16,记录余数(0-9 或 A-F),直到商为 0,然后反向排列余数。

示例:将十进制数 289 转换为十六进制

  • 289 ÷ 16 = 18 余 1(对应十六进制 1
  • 18 ÷ 16 = 1 余 2(对应十六进制 2
  • 1 ÷ 16 = 0 余 1(对应十六进制 1
  • 反向排列余数121
  • 验证:1×16² + 2×16¹ + 1×16⁰ = 256 + 32 + 1 = 289

2. 十六进制 → 十进制

方法:按位加权求和,权重为 16 的幂次(从右到左递增)。

示例:将十六进制数 0x3F7 转换为十进制

  • 3×16² + 15×16¹ + 7×16⁰
  • 768 + 240 + 7 = 1015

4、二进制 ↔ 八进制转换

1. 二进制 → 八进制

方法:从右到左每 3 位二进制分组,不足 3 位补零,每组转换为对应的八进制数字。

示例:将二进制数 1011010 转换为八进制

  • 分组001 011 010
  • 转换每组:001 → 1,011 → 3,010 → 2
  • 结果132
  • 验证:1×8² + 3×8¹ + 2×8⁰ = 64 + 24 + 2 = 90(与二进制 1011010 对应的十进制一致)

2. 八进制 → 二进制

方法:将每个八进制数字展开为对应的 3 位二进制数。

示例:将八进制数 72 转换为二进制

  • 展开每位:7 → 111,2 → 010
  • 结果111010

5、二进制 ↔ 十六进制转换

1. 二进制 → 十六进制

方法:从右到左每 4 位二进制分组,不足 4 位补零,每组转换为对应的十六进制数字。

示例:将二进制数 11010110 转换为十六进制

  • 分组1101 0110
  • 转换每组:1101 → D,0110 → 6
  • 结果0xD6
  • 验证:D×16¹ + 6×16⁰ = 13×16 + 6 = 214(与二进制 11010110 对应的十进制一致)

2. 十六进制 → 二进制

方法:将每个十六进制数字展开为对应的 4 位二进制数。

示例:将十六进制数 0x2A 转换为二进制

  • 展开每位:2 → 0010,A → 1010
  • 结果00101010 → 简化为 101010

6、快速转换技巧

  1. 二进制 → 八进制 / 十六进制

    • 二进制转八进制:每 3 位一组,直接映射(如 111 → 7)。
    • 二进制转十六进制:每 4 位一组,直接映射(如 1111 → F)。
  2. 八进制 / 十六进制 → 二进制

    • 八进制转二进制:每 1 位展开为 3 位(如 7 → 111)。
    • 十六进制转二进制:每 1 位展开为 4 位(如 F → 1111)。
  3. 多进制通用转换
    任何进制之间的转换都可以通过十进制作为中间桥梁进行:
    A进制 → 十进制 → B进制

7、常见进制对照表

十进制二进制八进制十六进制
0000000
1000111
2001022
3001133
4010044
5010155
6011066
7011177
81000108
91001119
10101012A
11101113B
12110014C
13110115D
14111016E
15111117

F

三、C++ 实现进制转换

以下是完整的 C++ 代码实现,包含了各进制之间的相互转换函数:

#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>// ===== 十进制转换为其他进制 =====
std::string decToBin(int num) 
{if (num == 0) return "0";std::string result;bool isNegative = num < 0;num = abs(num);while (num > 0) {result += (num % 2) ? '1' : '0';num /= 2;}if (isNegative) result += '-';std::reverse(result.begin(), result.end());return result;
}std::string decToOct(int num) 
{if (num == 0) return "0";std::string result;bool isNegative = num < 0;num = abs(num);while (num > 0) {result += (num % 8) + '0';num /= 8;}if (isNegative) result += '-';std::reverse(result.begin(), result.end());return result;
}std::string decToHex(int num) 
{if (num == 0) return "0";std::string result;bool isNegative = num < 0;num = abs(num);const char hexChars[] = "0123456789ABCDEF";while (num > 0) {result += hexChars[num % 16];num /= 16;}if (isNegative) result += '-';std::reverse(result.begin(), result.end());return result;
}// ===== 其他进制转换为十进制 =====
int binToDec(const std::string& bin) 
{int result = 0;bool isNegative = false;size_t start = 0;if (bin[0] == '-') {isNegative = true;start = 1;}for (size_t i = start; i < bin.size(); ++i) {result = result * 2 + (bin[i] - '0');}return isNegative ? -result : result;
}int octToDec(const std::string& oct) 
{int result = 0;bool isNegative = false;size_t start = 0;if (oct[0] == '-') {isNegative = true;start = 1;}for (size_t i = start; i < oct.size(); ++i) {result = result * 8 + (oct[i] - '0');}return isNegative ? -result : result;
}int hexToDec(const std::string& hex) 
{int result = 0;bool isNegative = false;size_t start = 0;// 跳过0x前缀if (hex.size() >= 2 && hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X')) {start = 2;} else if (hex[0] == '-') {isNegative = true;start = 1;}for (size_t i = start; i < hex.size(); ++i) {char c = toupper(hex[i]);int val;if (c >= '0' && c <= '9') {val = c - '0';} else if (c >= 'A' && c <= 'F') {val = 10 + (c - 'A');} else {throw std::invalid_argument("Invalid hex character");}result = result * 16 + val;}return isNegative ? -result : result;
}// ===== 二进制与八进制/十六进制互转 =====
std::string binToOct(const std::string& bin) 
{// 补全位数至3的倍数std::string padded = bin;while (padded.size() % 3 != 0) {padded = '0' + padded;}std::string result;for (size_t i = 0; i < padded.size(); i += 3) {std::string group = padded.substr(i, 3);int val = (group[0] - '0') * 4 + (group[1] - '0') * 2 + (group[2] - '0');result += std::to_string(val);}return result;
}std::string binToHex(const std::string& bin) 
{// 补全位数至4的倍数std::string padded = bin;while (padded.size() % 4 != 0) {padded = '0' + padded;}std::string result;const char hexChars[] = "0123456789ABCDEF";for (size_t i = 0; i < padded.size(); i += 4) {std::string group = padded.substr(i, 4);int val = (group[0] - '0') * 8 + (group[1] - '0') * 4 + (group[2] - '0') * 2 + (group[3] - '0');result += hexChars[val];}return result;
}std::string octToBin(const std::string& oct) 
{std::string result;for (char c : oct) {int val = c - '0';std::string bin = "";for (int i = 2; i >= 0; --i) {bin += ((val >> i) & 1) ? '1' : '0';}result += bin;}// 移除前导零size_t firstNonZero = result.find_first_not_of('0');return (firstNonZero != std::string::npos) ? result.substr(firstNonZero) : "0";
}std::string hexToBin(const std::string& hex) 
{std::string result;size_t start = 0;// 跳过0x前缀if (hex.size() >= 2 && hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X')) {start = 2;}for (size_t i = start; i < hex.size(); ++i) {char c = toupper(hex[i]);int val;if (c >= '0' && c <= '9') {val = c - '0';} else if (c >= 'A' && c <= 'F') {val = 10 + (c - 'A');} else {throw std::invalid_argument("Invalid hex character");}std::string bin = "";for (int i = 3; i >= 0; --i) {bin += ((val >> i) & 1) ? '1' : '0';}result += bin;}// 移除前导零size_t firstNonZero = result.find_first_not_of('0');return (firstNonZero != std::string::npos) ? result.substr(firstNonZero) : "0";
}// ===== 主函数演示 =====
int main() {// 测试数据int decNum = 255;std::string binNum = "11010110";std::string octNum = "377";std::string hexNum = "0xFF";// 十进制转换std::cout << "十进制转二进制: " << decNum << " → " << decToBin(decNum) << std::endl;std::cout << "十进制转八进制: " << decNum << " → " << decToOct(decNum) << std::endl;std::cout << "十进制转十六进制: " << decNum << " → " << decToHex(decNum) << std::endl;// 其他进制转十进制std::cout << "二进制转十进制: " << binNum << " → " << binToDec(binNum) << std::endl;std::cout << "八进制转十进制: " << octNum << " → " << octToDec(octNum) << std::endl;std::cout << "十六进制转十进制: " << hexNum << " → " << hexToDec(hexNum) << std::endl;// 二进制与八进制/十六进制互转std::cout << "二进制转八进制: " << binNum << " → " << binToOct(binNum) << std::endl;std::cout << "二进制转十六进制: " << binNum << " → " << binToHex(binNum) << std::endl;std::cout << "八进制转二进制: " << octNum << " → " << octToBin(octNum) << std::endl;std::cout << "十六进制转二进制: " << hexNum << " → " << hexToBin(hexNum) << std::endl;return 0;
}

 

四、代码解析与关键点

  1. 十进制转其他进制

    • 使用循环不断除以目标进制基数,保存余数后反向排列。
    • 处理负数时,先取绝对值,最后添加符号位。
  2. 其他进制转十进制

    • 按位加权求和,注意处理前缀(如0x)和符号位。
  3. 二进制与八进制 / 十六进制互转

    • 二进制 → 八进制 / 十六进制:按 3 位或 4 位分组,直接映射。
    • 八进制 / 十六进制 → 二进制:每 1 位展开为 3 位或 4 位。
  4. 字符串处理

    • 使用std::reverse反转字符串。
    • 处理前导零时,确保结果正确性(如0不会被移除)。

五、应用场景与注意事项

1. 实际应用

  • 嵌入式开发:直接操作二进制位(如寄存器配置)。
  • 网络编程:解析 IP 地址、端口号等二进制数据。
  • 密码学:处理哈希值、密钥等十六进制表示。

2. 注意事项

  • 溢出问题:转换大数值时需注意数据类型范围(如int vs long long)。
  • 字符大小写:十六进制字符需统一处理(如Aa均视为 10)。
  • 前缀处理:八进制(0)和十六进制(0x)的前缀需特殊处理。

相关文章:

  • Linux操作系统Shell脚本概述与命令实战
  • 【使用JAVA调用deepseek】实现自能回复
  • ffmpeg(三):处理原始数据命令
  • Quipus系统的视频知识库的构建原理及使用
  • 编译一个Mac M系列可以用的yuview
  • JAVA国际版一对一视频交友视频聊天系统源码支持H5+APP
  • Canal
  • L1-019 谁先倒 (15 分)
  • 每日算法 -【Swift 算法】三数之和
  • Fréchet Inception Distance(FID)
  • 自驾总结_Routing
  • Vue全局事件总线
  • Java编程常见错误与最佳实践
  • Numpy——结构化数组和Numpy文件
  • Hadoop企业级高可用与自愈机制源码深度剖析
  • Qt Quick快速入门笔记
  • 【Java】使用VarHandler实现无锁Stack
  • 具备强大的数据处理和分析能力的智慧地产开源了
  • 测试开发笔试题 Python 字符串中提取数字
  • C++ 使用 ffmpeg 解码 rtsp 流并获取每帧的YUV数据
  • 广州网站改版设计公司/销售新手怎么找客源
  • 深圳营销培训班/丁的老头seo博客
  • 户外做旅游网站/平面设计主要做什么
  • 安卓app软件公司/seo官网
  • 安全员c证电子证书查询/湖南seo推广多少钱
  • 网站推广方法有/网络营销课程主要讲什么内容