进制转换
十进制转二进制
十进制转二进制的方法是:除 2 取余,直到商为 0 为止,然后把余数倒过来就是二进制数。
比如:十进制数 10 转二进制数
10 / 2 = 5 余 0
5 / 2 = 2 余 1
2 / 2 = 1 余 0
1 / 2 = 0 余 1
所以 10 的二进制数为 1010
二进制转十进制
二进制转十进制的方法是:把二进制数从右往左排列,然后从 0 开始,每个数乘以 2 的 n 次方,n 从 0 开始,然后把结果相加。
比如:二进制数 1010
转十进制数
0 * 2^0 = 0
1 * 2^1 = 2
0 * 2^2 = 0
1 * 2^3 = 8
所以 1010
的十进制数为 10
十进制转十六进制
十进制转十六进制的方法是:除 16 取余,直到商为 0 为止,然后把余数倒过来就是十六进制数。
比如:十进制数 10 转十六进制数
10 / 16 = 0 余 10
所以 10 的十六进制数为 A
十六进制转十进制
十六进制转十进制的方法是:把十六进制数从右往左排列,然后从 0 开始,每个数乘以 16 的 n 次方,n 从 0 开始,然后把结果相加。
比如:十六进制数 A
转十进制数
10 * 16^0 = 10
所以 A
的十进制数为 10
二进制转十六进制
二进制转十六进制的方法是:先把二进制数每 4 位分成一组,然后把每组转成十六进制数,最后把结果拼接起来。
比如:二进制数 1010
转十六进制数
1010 -> 0000 1010 -> 0A
所以 1010
的十六进制数为 A
十六进制转二进制
十六进制转二进制的方法是:先把十六进制数转成十进制数,然后把十进制数转成二进制数。
比如:十六进制数 A
转二进制数
A -> 10 -> 1010
所以 A
的二进制数为 1010
设置文件夹
我在代码文件夹新建了 main.cpp
和 第一天/a.cpp
main.cpp
#include <iostream>
#include '第一天/a.cpp'
using namespace std;
int main() {
cout << "Hello World!" << endl;
return 0;
}
a.cpp
// 打印二进制
#include <iostream>
using namespace std;
void binaryTest() {
unsigned char binaryNumber = 0b0011;
cout << binaryNumber << endl;
// 位操作符
// unsigned char binaryNumber2 = (1 << 7) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 0);
unsigned int binaryNumber2 = (1 << 1) | (1 << 0); // 二进制数 0011
cout << binaryNumber2 << endl;
}
然后光荣报错
duplicate symbol 'binaryTest()' in:
CMakeFiles/cpp_study.dir/main.cpp.o
CMakeFiles/cpp_study.dir/第一天/a.cpp.o
duplicate symbol 'printBinary(int)' in:
CMakeFiles/cpp_study.dir/main.cpp.o
CMakeFiles/cpp_study.dir/第一天/a.cpp.o
ld: 2 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
解决方法
新建头文件 a.h
#ifndef CPP_STUDY_A_H
#define CPP_STUDY_A_H
void binaryTest();
void printBinary(int number);
#endif //CPP_STUDY_A_H
然后在 main.cpp
和 a.cpp
中引入头文件
main.cpp
#include <iostream>
#include '第一天/a.h'
....
a.cpp
#include <iostream>
#include "a.h"
....
写一个进制字面量
unsigned char binaryNumber = 0b11001111;
cout << binaryNumber << endl;
// 位操作符
unsigned char binaryNumber2 = (1 << 7) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 0);
cout << binaryNumber2 << endl;
竟然打印出了两个乱码
问群友
Rex 大佬直出 0b11001111 也就是 207,标准 ASCII 没有对应的字符吧
我一看还真是,改成 1100
unsigned char binaryNumber = 0b1100;
cout << binaryNumber << endl;
// 位操作符
unsigned int binaryNumber2 = (1 << 1) | (1 << 0); // 二进制数 0011
cout << binaryNumber2 << endl;
这次控制台打印的
(你们可能看不到,是 ext)
3
在 ASCII 编码中,字符 (ETX,End of Text)对应的是一个控制字符,它的十进制值是 3。而二进制数 0011 表示的是十进制数 3。
重温八进制和十六进制
// 定义八进制字面量
unsigned int octalNumber = 0123;
// 1 * 8^2 + 2 * 8^1 + 3 * 8^0 = 64 + 16 + 3 = 83
cout << octalNumber << endl;
// 定义十六进制字面量
unsigned int hexadecimalNumber = 0x123;
// 1 * 16^2 + 2 * 16^1 + 3 * 16^0 = 256 + 32 + 3 = 291
cout << hexadecimalNumber << endl;
反码和补码
反码和补码是计算机中用于表示负数的两种常见方式。它们的存在是为了解决在计算机系统中处理负数运算和表示的问题。
反码(One’s Complement)
反码是一种表示负数的方法,其中正数保持不变,而负数则通过对其二进制表示的每一位取反(0 变为 1,1 变为 0)来表示。例如,正数 5 的二进制是 0101,负数 -5 的反码是 1010。这样,计算机可以使用相同的加法和减法操作来处理正数和负数。
但是,反码有一个问题,就是有两个表示零的值,分别是正零和负零,即 0000 和 1111 都表示零。这会引入一些运算上的复杂性。
补码(Two’s Complement)
为了克服反码的零的问题,并且能够更方便地进行负数运算,补码被引入。补码也是一种表示负数的方式,其中负数是其对应正数的反码加 1。例如,正数 5 的二进制是 0101,负数 -5 的补码是 1011。
补码的一个重要特性是,通过对补码进行加法和减法运算,可以在不考虑正负的情况下,得到正确的结果。而且,补码只有一个表示零的值,即 0000,没有正零和负零的区分。
在现代计算机中,大多数都使用补码来表示负数。这是因为补码在进行运算时更加方便,而且只有一个零的表示。补码也有助于简化硬件电路的设计和实现。