01-Information_Representation

Note

The number represented by the computer's internal code is called machine number, and the corresponding value is called true value.

I Numeric

I.1 Integer number (fixed-point)

I.1.1.1 Unsigned integer

Just like what binary number do

0X2n1

I.1.1.2 Signed integer
I.1.1.2.1 Original Code

The original code representation of a number consists of the sign bit followed by the value bit, also known as sign-and-magnitude representation.

|500

但是这样具有不少 缺点

I.1.1.2.2 Inverse Code

反码能够解决一部分问题。

一个很好的解决办法是用补码表示,然后惊奇地发现所有问题都解决了,这也是补码存在的意义,在上一篇 Inverse code & Complement code(反码&补码) 的讲解也很清楚了

I.1.1.2.3 Complement Code

最后一条是我从后面挪过来的,也就是说在符号扩展后,表示数值不变。

例如,4 位下的 -3 的补码是 1101,符号扩展至 8 位后为 1111 1101,依旧是 -3,这也是因为 1 在取反后全部变为了 0,并不会有所影响。

对于一个 N 位二进制数来说,M=2N

|500

Question

如果是 [XT]c[XT]c 呢?

连带着符号位一起取反就好了。

I.1.2 number range

|500

|500

I.1.3 Floating-point number representation

I.1.4 sign change

我们在使用过程中不免碰到无符号整型和有符号整型相互转换,虽然我们可能能够实现,但是往往会存在许多安全漏洞

Note

在 C 语言中我们有显式转换和隐式转换。

其中,显式转换如下:

  • tx = (int) ux;

  • ux = (unsigned) tx;

而对于隐式转换常出现在比较运算中,如 >= == != 中,下面是一些例子,但是都遵循以下特点:

Attention

If there is a mix of unsigned and signed in single expression, signed values implicitly cast to unsigned


[!NOTE]

"显式转换的危害"

显式转换也是强制转换,这意味着如果不怀好意就可以干一些坏事,看下面一个例子

  #include <iostream>
  using namespace std;
  int main()
  {
    cout << (((unsigned)-5) > 12) << endl;
    cout << (unsigned)-5 << endl;
  }

结果输出为 1 4294967291

I.1.4.1 sign extension

|500

上面是对于有符号数(t) 而言的,对于无符号数 (u) 则 直接补 0

I.1.4.1.1 example

I.1.4.1.2 code
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    short int x = -15213;
    cout << x << endl;
    cout << (int)x << endl;
    printf("%u\n", x); // 将x转为无符号整型输出
    printf("%x\n", x); // 将x转为十六进制整型输出
    return 0;
}

-15213

4294952083

ffffc493

-15213

I.1.5 addition

I.1.5.1 unsigned addition
I.1.5.1.1 Truncating(数据截断)
Definition

数据截断是直接将高位丢弃,其实相当于进行了模除操作

运用在机器加法上就表现在丢弃高位的进位

|500

将其可视化:

|500

I.1.5.1.2 Mathematical Properties

Modular Addition Forms an Abelian Group:

|500

I.1.5.2 two's complement addition

仍旧存在高位截断的情况,并且在两个较小的负数(negover) 或者两个较大正数(posover) 相加时都会产生溢出

|500

因此可视化如下:

|500

I.1.5.2.1 Mathematical Properties

|500

I.1.6 multiplication

|500

I.1.6.1 example

|500

一个简单的例子,我们知道 int 可代表的最大数为 2311 ,我们让 ele_cnt * ele_size 等于 232 ,由于高位截断,实际分配的空间肯定没有这么多,但是我们确确实实拷贝了这么长的数据,会发生什么?多拷贝的数据依旧是线性排列,挤入它本不该去的地方;这十分危险。

I.1.6.2 implement

我们可以用 shift operation (移位操作) 来实现乘法

Question

Most machines shift and add faster than multiply, so compiler generates this code automatically

如果我们希望更加符合直觉,取整向 0 靠齐,即正数向下取整,负数向上取整,我们可以计算

x+2k1k

验证略

I.1.7 Properties of Unsigned & Two’s Comp.Arithmetic

|500

环的概念和阿贝尔群放在一起了

|500

I.2 Float point number

Cite

IEEE Standard 754

  • Nice standards for rounding, overflow, underflow

  • Hard to make fast in hardware

I.2.1 Floating Point Representation

I.2.1.1 form

|500

Info

|500

其中 E 也称为 阶码,我们下面以单精度浮点数为例进行讲解

|500

I.2.1.1.1 Normalized Values

这一储存形式称为 Normalized Values(规范化形式)

|500

在我们右移操作时,对于数据溢出,在整型数中被舍去;而在浮点数中,我们用一段内存(frac) 来将其存储,即为 M(M 范围为 [1.0,2.0) ,类比科学计数法不难理解),下面是一个例子

|500

I.2.1.1.2 Denormalized Values

而当我们需要储存一个非常接近于 0 的数(exp = 000...00)时,我们不使用 normalized values,而使用 Denormalized Values (非规范化形式)

|500

I.2.1.1.3 Special values

当我们去储存一个很大的数时(exp = 111...11),我们使用 special values

    float x = 1.0;
    double y = 1.0;
    cout << (x / 0.0) << endl;
    cout << (y / 0.0) << endl;
    cout << (1.0 / 0.0) << endl;
    cout << (0xff / 0.0) << endl;
// 输出全为 `inf`

E.g., sqrt(–1), ;0

Abstract

有点绕,看看 xg的笔记,详细计算的方法写的很详细,不解释了,老师也讲了(虽然看了半天才明白……)

I.2.1.1.4 example

Question

how to compare integer with float point?


[!NOTE]

舍入(rounding)有四种:向偶舍入(round-to-even,默认项)、向 0 舍入(round-toward-zero)、向下舍入(round-down)、向上舍入(round-up)

I.2.1.1.5 Mathematical Properties of FP Mult

|500

II non-numeric

II.1 Representation of logical values

II.1.1 ASCII 码

全称 American Standard Code for Information Interchange ,表如下

|500

下面这段话介绍了这张表格的构成

Quote

The seven bits of the code are designated by B 1 through B 7, with B 7 being the most signficant bit. Note that the most signiicant three bits of the code determine the column of the table and the least significant four bits the row of the table.

对于控制字符我们暂且不考虑。

II.1.2 校检位

基于 ASCII 码的七位,我们根据其中 1&0 的数量加入一个 1 / 0 (parity 1)补充成八位后发送,在接收端会同样生成校检位(parity 2)。倘若发送过程中有奇数位发生了变化,parity1parity2 ,那么就发现了错误(偶数位变化另谈)

II.1.3 Gray code(格雷码)

专注于转轴的编码,大大节省了在相邻数字之间切换的开销

此处略讲,部分可以参看 HobbitQia的笔记本进行学习

II.2 Representation of Chinese Characters

|500