Preview

这个系列只是我学计算机系统基础的笔记,所以说目录不是很整齐。

我也只会记一些重要的东西。

本文刚好解决了昨天的一个问题:

为什么 -2147483648 < 2147483647 的返回结果为 false?

变形补码

双符号位,用于存放可能的溢出的中间结果。

一般用于值太大,用 4位补码 无法表示,故 “ 溢出 ” 但用变形补码可保留符号位和最高数值位。

img

取反加一的由来

上一篇我写补码部分过于仓促,只写了一句:

整数补码是他本身,负数补码要将原码取反加一。

仔细一想,我自己也不知道为啥要取反加一,所以又去学了学。

定义

img

我们举个例子,写出详细的计算过程:

设机器数为 8 位,求 -123 的补码

img

简便方法:负数求补码从右往左数,找到第一个 “ 1 ”,然后将 1 左边的取反即可。不对第一位取反,相当于加一。

补码求真值,有两种方法:

1、减一取反

2、取反加一

C语言中基本的数据类型

img

小贴士来啦!

通常在一个数后面加上 ” u “ 或 ” U “ 表示该数为无符号整数。

我现在才知道之前做逆向题,IDA 伪代码里的 u 是啥意思。。。。。

我是土狗。

img

无符号数和有符号数

img

可以从表中看出来,带*的都是与正确结果相反的,这就是符号位引起的一些变化。

这时我们过头来看一下第一篇中提出的问题:

为什么 -2147483648 < 2147483647 的返回结果为 false?

要解决这个问题,我们就要搞清楚,编译器在处理这些常量时候进行的操作。

但是目前来看,关系式中既没有强制类型转换,也没有 U 的出现。

所以说,这个比较是在两个有符号数之间进行的。要高明白其中的原理,需要了解编译器处理常量的操作:

编译器处理常量时默认的数据类型:

img

以上的内容会受 C语言标准 的影响,就是左侧的 C90 C99 是两个不同的标准

【C90 (ISO C)】 随后,《The C Programming Language》第二版开始出版发行,书中内容根据 ANSI C(C89)进行了更新。1990 年,在 ISO/IEC JTC1/SC22/WG14 (ISO/IEC 联合技术第 I 委员会第 22 分委员会第 14 工作组) 的努力下,ISO 批准了 ANSI C 成为国际标准。于是 ISO C(又称为 C90) 诞生了。除了标准文档在印刷编排上的某些细节不同外,ISO C(C90) 和 ANSI C(C89) 在技术上完全一样。

【C99】 1999 年,ANSI 和 ISO 又通过了最新版本的 C 语言标准和技术勘误文档,该标准被称为 C99 。这基本上是目前关于 C 语言的最新、最权威的定义了。

具体区别可以看这篇文章(http://c.biancheng.net/view/143.html)或者自行百度

🍊从图中我们可以看出来,在未指定类型的常量中,计算机会根据相应的范围,自动给出数据类型。这也导致了 bug 的产生。

🌟问题中的 “ -2147483648 ” 为 2^31 所以计算机将其定义为 unsigned int(无符号数)

所以判断的结果才是错误的。

那么这个式子理解起来就简单了:

-2147483647 - 1 < 2147483647

当计算机处理这个常量时,因为 -2147483647 为 2^31 - 1 所以将其定义为 int 然后 -1。

这个考点挺好玩的,可以考虑给新生的招新赛出一道这样的题目。

img

浮点数(实数)

计算机中存储实数的方法类似于我们平常使用的科学计数法:

img

前面这部分叫做 定点小数,后面的那部分叫做 定点整数。

img

🍊关于这里的移码,以及为什么要用移码来表示阶数(方便对阶),可以去看一下第一篇文章,关于移码的那部分,两个结合起来看更容易理解。

🍎上述的仅仅作为例子,这样更方便理解,然而我们常用的浮点数表示形式,是 IEEE 754 标准

IEEE 754

img

与我举的例子不同的地方,就是 IEEE 754 规定在小数点前必须为 1 ,这样比例子的表示范围广更大,可以表示更多地有效数字。

Summary

今天的学习效率有些许(特别多)的下降,一整天也没学多少东西。

学校的实训政策属实逆天,让人留校,但是不保证学生的吃饭和洗澡问题,餐厅都关门了。

👴非常生气,搞的都学不进去。

虽然说很大一部分原因都是因为控制不住自己玩手机。

img

今天的这些东西,都需要动手算一算,或者找个调试软件试试,要不然很难理解。

OVER!

明天继续!

今日壁纸:

img