第二章 信息的处理和表示

    技术2022-07-12  92

    2.1 信息存储

    冯·诺依曼体系计算机都是以二进制形式存储数据的,每个数据称为位。 8个位组成一个字节,一个字节是最小的可寻址内存单位。 内存每个字节都由唯一的数字来标识,称为地址。

    2.1.3 寻址和字节顺序

    0x01234567

    大端法 最高有效字节在前

    0x1000x1010x1020x10301234567

    0x01234567

    小端法 最高有效字节在后

    0x1000x1010x1020x10367452301

    2.1.7 C语言的位级运算

    & 与运算符 0 & 1 -> 0 | 或运算符 0 | 1 -> 1 ~ 非运算符 ~0 -> 1 ^ 异或运算符

    0 ^ 11 ^ 10^ 0100

    javascript Javascript中没有整数类型…只有双精度浮点数。因此,位操作数符把它们的数字运算数先转换成整数,接着执行运算符,然后再转换回去。 大多数语言中,这些位运算符非常接近于硬件处理,所以很快。但Javascript的执行环境一般接触不到硬件,所以很慢。Javascript很少用来执行位操作。

    2.2 整数表示

    C语言中不同数据类型表示的数字范围是有限的。

    用4位表示一个整数。 无符号数[1111] = 15 补码[1111] = -1

    关键还是在于最高位的权重不同 无符号数最高位 2 ^ 3 = 8

    有符号数最高位 (-1)* 2 ^ 3 = -8

    2.2.4 有符号和无符号之间的转换

    底层位数值不变,只是解释不同。

    无符号数[1111] = 15 补码[1111] = -1

    T2U(-1) = UMax 在位级上 补码-1 等于 最大的无符号数

    2.2.8 有符号数和无符号数的建议

    建议就是没什么事儿别用无符号数… 大部分高级编程语言都是用补码表示数字的

    float sum_elements(float a[], unsigned length) { int i; float result = 0; for (i = 0; i <= length - 1; i++){ result += a[i]; } return result; }

    这里的 length - 1是无符号数减一个有符号数 C语言会将进行无符号数运算 如果length值为0,0 - 1 //=> -1 即 [1111] 这样就会转为非常大的数字

    参考隐式类型转换规则: 因此for循环会访问数组的非法地址。

    2.3 整数运算

    2.3.1无符号加法

    9:[1001] 12:[1100] 两个数相加得 [10101] 因为只有4位表示数字,最高位会被截断,即得到5:[0101]

    这相当于 (9+12)mod 16 = 5

    2.3.2 补码加法

    x + y = s

    正溢出负溢出x >= 0, y >= 0, s < 0x < 0, y< 0, s>0

    溢出都是因为位的数量不足以表示一个数,超出了可表示的范围,就发生了截断。

    2.4浮点数

    因为浮点数表示的特性,特别适合表示2^-10非常趋近于0的数字以及2^10这样远大于1的数字

    在控制台打印这样的数字 打印a会发现后面的小数点没了…

    这与浮点数表示数字的特性有关

    看一个例子就能明白 float f = 15213.0 转成二进制表示就是 1.11011101101101 * 2^13

    2^13 的13 13 + bias = 140 即二进制 10001100 放入exp阶码

    1.11011101101101 11011101101101前面的1 省略,因为表示的形式永远都以1.xxxxx 剩余的11011101101101 放入frac 尾数部分

    js中使用IEEE 754 双精度,类似于C语言的double类型 那么这样的一个数字

    var a = 200000000000000000.0000000000002;

    //=> 表示起来就是这样

    101100011010001010111100001011101100010110100001110110111011

    1.01100011010001010111100001011101100010100001110110111011 * 2 ^ 64 将近60+位

    不可能全放入尾数部分,double类型尾数只有52位,后面的全部舍去。

    最后只能得到这样的数字(后面全部舍去)

    011000110100010101111000010111011000101000000000000000000

    因此

    200000000000000000.0000000000002

    小数的部分就被舍去了,因为精度有限

    2020/7/2 第一次总结

    Processed: 0.009, SQL: 9