mirror of
https://github.com/Aexiar/c.git
synced 2024-10-22 14:05:45 +02:00
c
This commit is contained in:
parent
d57207c1ae
commit
8cbdfd4d1a
4
docs/notes/01_c-basic/02_xdx/assets/43.svg
Normal file
4
docs/notes/01_c-basic/02_xdx/assets/43.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 443 KiB |
4
docs/notes/01_c-basic/02_xdx/assets/44.svg
Normal file
4
docs/notes/01_c-basic/02_xdx/assets/44.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 156 KiB |
@ -1321,3 +1321,62 @@ int main() {
|
|||||||
>
|
>
|
||||||
> `补码`这种天才般的设计,一举达成了之前加法运算和减法运算提到的两个目标,简化了硬件电路。
|
> `补码`这种天才般的设计,一举达成了之前加法运算和减法运算提到的两个目标,简化了硬件电路。
|
||||||
|
|
||||||
|
## 3.8 问题引入
|
||||||
|
|
||||||
|
* 在 C 语言中,对于`有符号位`的整数,是使用 `0` 作为正数,`1` 作为负数,来表示`符号位`,并使用`数据位`来表示的是数据的`真值`,如下所示:
|
||||||
|
|
||||||
|
```c
|
||||||
|
int a = 10;
|
||||||
|
int b = -10;
|
||||||
|
```
|
||||||
|
|
||||||
|
![](./assets/43.svg)
|
||||||
|
|
||||||
|
* 但是,对于`无符号位`的整数而言,是`没有`符号位和数据位,即:没有原码、反码、补码的概念。无符号位的整数的数值都是直接使用二进制来表示的(也可以理解为对于无符号位的整数而言,计算机底层存储的就是其原码),如下所示:
|
||||||
|
|
||||||
|
```c
|
||||||
|
unsigned int a = 10;
|
||||||
|
unsigned int b = -10;
|
||||||
|
```
|
||||||
|
|
||||||
|
![](./assets/44.svg)
|
||||||
|
|
||||||
|
* 这就是导致了一个结果就是:如果我定义一个`有符号`的负数,却让其输出`无符号`,必然造成结果不对,如下所示:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
char *getBinary(int num) {
|
||||||
|
static char binaryString[33];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = sizeof(num) * 8 - 1, j = 0; i >= 0; i--, j++) {
|
||||||
|
const int bit = (num >> i) & 1;
|
||||||
|
binaryString[j] = bit + '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
binaryString[j] = '\0';
|
||||||
|
return binaryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// 禁用 stdout 缓冲区
|
||||||
|
setbuf(stdout, NULL);
|
||||||
|
|
||||||
|
int num = -10;
|
||||||
|
printf("b=%s\n", getBinary(num)); // b=11111111111111111111111111110110
|
||||||
|
printf("b=%d\n", num); // b=-10
|
||||||
|
printf("b=%u\n", num); // b=4294967286
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* 其实,C 语言的底层逻辑很简单,C 语言压根不关心你定义的是有符号数还是无符号数,它只关心内存(如果定义的是有符号数,那就按照有符号数的规则来存储;如果定义的是无符号数,那就按照无符号数的规则来存储)。换言之,有符号数可以按照无符号数来输出,无符号数也可以按照有符号数来输出,至于输出结果对不对,那是程序员的事情,和 C 语言没有任何关系。
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
>
|
||||||
|
> * ① 正因为上述的原因,很多现代化的编程语言,如:Java 等,直接取消了无符号的概念。
|
||||||
|
> * ② 对于 `1000 0000 …… 0000 0000` 是个特殊的补码,无法按照上述的方法转换为原码,所以计算机直接规定这个补码对应的值就是 `-2³¹`,至于为什么,下节我们会详细分析。
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user