【C#学习笔记03】进制转换与反码、补码、原码

1. 进制转换

计算机中的数据通常以二进制形式存储,但在编程和调试过程中,我们经常需要与十进制、八进制和十六进制打交道。因此,掌握进制转换是C语言学习中的重要一环。


1.1 进制的基本概念

  • 二进制(Binary) :基数为2,使用数字0和1。
  • 八进制(Octal) :基数为8,使用数字0到7。
  • 十进制(Decimal) :基数为10,使用数字0到9。
  • 十六进制(Hexadecimal) :基数为16,使用数字0到9和字母A到F。

1.2 进制转换方法

1.2.1 二进制转十进制

将二进制数的每一位乘以2的幂次方,然后相加。

将二进制数​​1011​​​转换为十进制:

cs 复制代码
1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 1 * 2^0
= 8 + 0 + 2 + 1
= 11
1.2.2 十进制转二进制

通过不断除以2并记录余数,直到商为0,然后将余数倒序排列。

将十进制数​​11​​​转换为二进制:

cs 复制代码
11 / 2 = 5 余 1
5 / 2 = 2 余 1
2 / 2 = 1 余 0
1 / 2 = 0 余 1

倒序排列余数:​​1011​​。


1.2.3 二进制转八进制

将二进制数从右到左每三位一组,不足三位补零,然后将每组转换为对应的八进制数。

将二进制数​​101110​​​转换为八进制:

cs 复制代码
101 110
5   6

结果为​​56​​。


1.2.4 二进制转十六进制

将二进制数从右到左每四位一组,不足四位补零,然后将每组转换为对应的十六进制数。

将二进制数​​101110​​​转换为十六进制:

cs 复制代码
0010 1110
2    E

结果为​​2E​​。


1.2.5 十进制转十六进制

通过不断除以16并记录余数,直到商为0,然后将余数倒序排列。

将十进制数​​255​​转换为十六进制:

cs 复制代码
255 / 16 = 15 余 15 (F)
15 / 16 = 0 余 15 (F)

倒序排列余数:​​FF​​。


2. 反码、补码和原码

计算机可以区分整数的正负,但是程序最终都会被转换为二进制指令,二进制可以分正负,在二进制数的前面添加1bit,作为符号位,并且bit=0,用于表示二进制数为正数,bit=1,用于表示二进制数为负数。

可以知道,计算机内部是以二进制的补码方式来存储数据的,所以需要把二进制数的原码转换为补码形式。

可以知道,正数的原码和补码是相同的,所以负数才需要把原码转换为补码,再进行存储!


2.1 原码

原码是二进制数的最基本表示形式,最高位为符号位(0表示正数,1表示负数),其余位表示数值。

  • ​+5​的原码:​00000101​
  • ​-5​的原码:​10000101​

原码表示法存在以下问题:

  • 0有两种表示形式:​00000000​(+0)和​10000000​(-0)。
  • 加减法运算复杂,需要额外的硬件支持。

2.2 反码

反码是对原码的改进,正数的反码与原码相同,负数的反码是对其原码的符号位不变,其余位取反。

  • ​+5​的反码:​00000101​
  • ​-5​的反码:​11111010​

反码表示法仍然存在以下问题:

  • 0有两种表示形式:​00000000​(+0)和​11111111​(-0)。
  • 加减法运算仍然复杂。

2.3 补码

补码是计算机中表示有符号整数的标准方式。正数的补码与原码相同,负数的补码是其反码加1。

  • ​+5​的补码:​00000101​
  • ​-5​的补码:
  • 原码:​10000101​
  • 反码:​11111010​
  • 补码:​11111011​
  • 0只有一种表示形式:​00000000​
  • 加减法运算统一,可以直接使用加法器实现。

补码的运算

补码的一个重要特性是,一个数的补码的补码等于其原码。因此,补码可以方便地用于表示负数和进行减法运算。

计算​​5 - 3​​:

  • ​5​的补码:​00000101​
  • ​-3​的补码:​11111101​
  • 相加:​00000101 + 11111101 = 00000010​(结果为​2​)。

注意:设计程序时,定义的变量如果是有符号的,则尽量避免写入超过变量范围的数值!!!!!!

字符型: char 1字节 -- 有符号 -- 数值范围 -128 ~ 127 -- 无符号 -- 数值范围 0 ~ 255

短整型:short 2字节 -- 有符号 -- 数值范围 -32768 ~ 32767 无符号 --数值范围 0 ~ 65535


3. C语言中的进制表示与位操作

3.1 进制表示

  • 二进制 :C语言不支持直接表示二进制数,但可以通过前缀​0b​​0B​表示(某些编译器支持)。
  • 八进制 :以​0​开头,如​012​表示十进制的​10​
  • 十六进制 :以​0x​​0X​开头,如​0x1A​表示十进制的​26​
cs 复制代码
#include <stdio.h>

int main() {
    int binary = 0b1010;  // 二进制,值为10
    int octal = 012;      // 八进制,值为10
    int hexadecimal = 0x1A;  // 十六进制,值为26
    printf("Binary: %d\n", binary);
    printf("Octal: %d\n", octal);
    printf("Hexadecimal: %d\n", hexadecimal);
    return 0;
}

输出

cs 复制代码
Binary: 10
Octal: 10
Hexadecimal: 26

3.2 位操作

C语言提供了以下位操作运算符:

  • 按位与( &:对应位都为1时结果为1,否则为0。
  • 按位或( |:对应位有一个为1时结果为1,否则为0。
  • 按位异或( ^:对应位不同时结果为1,否则为0。
  • 按位取反( ~:将所有位取反。
  • 左移( <<:将二进制数向左移动指定位数,低位补0。
  • 右移( >>:将二进制数向右移动指定位数,高位补符号位(算术右移)或0(逻辑右移)。
cs 复制代码
#include <stdio.h>

int main() {
    int a = 5;  // 二进制:00000101
    int b = 3;  // 二进制:00000011

    printf("a & b: %d\n", a & b);  // 00000001 (1)
    printf("a | b: %d\n", a | b);  // 00000111 (7)
    printf("a ^ b: %d\n", a ^ b);  // 00000110 (6)
    printf("~a: %d\n", ~a);        // 11111010 (-6,补码表示)
    printf("a << 1: %d\n", a << 1);  // 00001010 (10)
    printf("a >> 1: %d\n", a >> 1);  // 00000010 (2)
    return 0;
}

输出

cs 复制代码
a & b: 1
a | b: 7
a ^ b: 6
~a: -6
a << 1: 10
a >> 1: 2
相关推荐
猪猪虾的业余生活1 分钟前
Qt 驾校考试系统项目实现
开发语言·qt
香菇滑稽之谈3 分钟前
责任链模式的C++实现示例
开发语言·c++·设计模式·责任链模式
风莫寻24 分钟前
【Troubleshot】Qt 长按按键 keyPressEvent keyReleaseEvent 自动重复问题
开发语言·qt
ZC·Shou24 分钟前
Rust 之一 基本环境搭建、各组件工具的文档、源码、配置
开发语言·rust·cargo·rustc·rustup·clippy·rustfmt
Hello.Reader26 分钟前
深入理解 Rust 中的模式匹配语法
开发语言·rust
最胖的小仙女30 分钟前
通过动态获取后端数据判断输入的值打小
开发语言·前端·javascript
阿波拉35 分钟前
AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas’问题解决
开发语言·python
瑶光守护者1 小时前
并行计算编程模型的发展方向与RISC-V的机遇
人工智能·笔记·学习·架构·risc-v
半夏知半秋1 小时前
linux下的网络抓包(tcpdump)介绍
linux·运维·服务器·网络·笔记·学习·tcpdump
臣妾写不来啊1 小时前
使用dify的api连接外部知识库,dify连接ragflow的知识库(附java代码)
java·开发语言·spring boot