第二章 信息的表示和处理

信息存储

  • 大多数计算机以字节(1 byte = 8 bits)作为最小可寻址的内存单位。

  • 虚拟内存:机器级程序将内存视为字节数组。

  • 地址:标识每个字节的唯一数字。

  • 虚拟地址空间[1]:所有可能的地址集合。

十六进制

十六进制的表示
  • 前缀0x/0X,字母可用大写A - F或小写a - f

    记住A,C,F的十进制值

十六进制与二进制、十进制的转化
  • 十六进制&二进制:四位二进制转化为一位十六进制,位数缺少时整数部分左侧补零,小数部分右侧补零。

  • 十六进制&十进制:乘除法

    2的非负整数n次幂转化为十六进制:n = i + 4 * j (i = 1, 2, 3)时,十六进制表示为2的 i 次方后有 j 个0

字数据大小

  • 字长决定了虚拟地址空间的最大大小:字长w位,虚拟地址范围为0 ~ 2^w - 1,即可以访问2^w个字节

  • 程序时32位还是64位取决于它是如何编译的。

2-1.png

寻址和字节顺序

  • 多字节对象被存储为连续的字节序列。

  • 字节存储顺序:一个数据类型内部字节的存储顺序

    • 大端法:高位字节优先存储

    • 小端法:低位字节优先存储

      大端法(big endian)和小端法(little endian)取自《格列佛游记》中打破鸡蛋的方式。原文暗讽英法两国持续的战争,而这里则暗示选择两种存储顺序没有技术上的理由,无谓好坏。

  • 需要注意字节存储顺序的三种情况

    • 不同机器通过网络传送二进制数时,由小端法机器传送给大端法机器的字节顺序会被认为是反序,反之亦然。此时应统一编写网络应用程序的字节顺序规则,由发送方机器将其内部表示先转化为网络标准,再由接收方机器将收到的网络标准转化为其内部表示

    • 阅读小端法机器的程序表示时。

    • 规避正常类型系统时,即运用了强制类型转换或联合。例如:运用强制类型转换生成对象的字节表示。

      #include<stdio.h>
      
      typedef unsigned char *byte_pointer; //指向字节序列的指针
      
      void show_bytes(byte_pointer start, size_t len){
          size_t i; //size_t是表示数据结构大小的首选数据类型(这里为sizeof的结果)
          for(i = 0; i < len; i++) printf("%.2x", start[i]); //%.2x表示两位16进制数
          printf("\n");
      }
      
      void show_int(int x){
          show_bytes((byte_pointer) &x, sizeof(int));
      }
      
      void show_float(float x){
          show_bytes((byte_pointer) &x, sizeof(float));
      }
      
      void show_pointer(void *x){
          show_bytes((byte_pointer) &x, sizeof(void *));
      }
      //这里的强制类型转换并未改变指针, 只是告诉编译器以新的数据类型看待被指向的数据
      //例如, show_int中将&x看作int指针时, 进入"下一个"地址会跨越四个字节; 看作char指针时, 进入"下一个"地址只会跨越1个字节
      

表示字符串

  • 字符串编码以null(0x00)结尾。
  • 最常见的字符编码是ASCII码。字符串的字节序列在使用ASCII编码的任何系统上都有相同结果,与字节顺序规则和字长大小无关。

表示代码

  • 从机器的角度看,程序代码只是字节序列。
  • 不同机器对于相同程序的二进制编码不同且不兼容。

布尔代数

  • 位向量可用于表示有限集合的子集,位向量的与或非等价于集合的交并补。
  • 布尔代数与整数算术有相似之处:交换律,结合律,分配律(布尔代数的分配律可以理解为对整数算术分配律的推广。因为布尔代数中,不仅&对|有分配律,|对&也有分配律)

C语言中相关运算

位级运算:&,|,~
  • 掩码运算掩码表示从一个字中选出的位的集合,如0xFF表示一个字低位字节都是1。x&0xFF表示x的最低字节不变,其他字节都被置为0。

    习题2.10&2.11

    注意:指向相同地址的两个指针,改变其中一个,则另一个也会变

    #include<stdio.h>
    #include<stdlib.h>
    
    void inplace_swap(int *x, int *y){
        *y = *x ^ *y;
        *x = *x ^ *y;
        *y = *x ^ *y;
    }
    
    void reverse_array(int a[], int cnt){
        int first, last;
        for(first = 0, last = cnt - 1; first <= last; first++, last--)
            inplace_swap(&a[first], &a[last]);
    }
    
    int main(){
        int a[5] = {1, 2, 3, 4, 5};
        reverse_array(a, 5);
        for(int i = 0; i < 5; i++) printf("%d", a[i]);
        //最终结果为{5,4,0,2,1}, first = last时, *x = *y, *y = *x ^ *y = 0时, *x也被置为0
        return 0;
    }
    
逻辑运算:&&,||,!
  • 逻辑运算中,只有0(FALSE)和1(TRUE),所有非零参数均表示1(TRUE)
  • 逻辑运算具有提前终止的特点。当第一个参数就能确定表达式的值时,就不会计算第二个参数。
移位运算:<<,>>
  • 左移即在低位补0。右移分为逻辑右移算术右移。逻辑右移在高位补0,算术右移在高位补符号位。
  • 由w位组成的数据,移动k位。若k>w,则只视为移动k mod w位。移位指令只考虑移位量k的低logw位。
  • 移位运算符合左结合律:x<<j<<k = (x<<j)<<k
  • 移位运算优先级低于加减法:x<<a+b<<k = (x<<(a+b))<<k

整数表示

整形数据表示

  • unsigned / (signed) + char, short, int, long
  • 数据类型取围:32位、64位、C语言标准均有不同

编码

无符号数(Unsigned)
  • B2U
  • UMax, UMin
  • 无符号数编码具有唯一性(B2U是双射)
补码(Two's-Complement)
  • B2T

  • TMax, TMin

    -TMax = 0 - TMax = TMax

  • 补码编码具有唯一性(B2T是双射)

  • |TMin| = TMax + 1

  • UMax = 2 * TMax + 1

  • -1和UMax有相同的位模式

  • 有符号数的其他表示方法

    • 原码(Sign-Magnitude)
    • 反码(Ones'-Complement):对于无符号数x,-x的w位表示在反码中相当于[11…1] - x,在补码中相当于2^w - x
无符号数和有符号数之间的转换
  • 保持位模式不变

  • 对于x,0≤x≤TMax时T2U(x) = U2T(x),否则转换时需对x加上或减去2^w

2-2.png
C语言中无符号数与有符号数的转换
  • 显示转换:强制类型转换
  • 隐式转换
    • 不同类型变量赋值:保持被赋值的变量类型不变
    • 输出函数printf中通过"%d"与"%u"进行转换
    • 运算中,如果有符号数和无符号数同时出现,则视为无符号运算

扩展位表示

  • 无符号数进行零扩展,值不变。
  • 有符号数进行符号扩展,值不变。
    • 高位全是1和只有最高位为1对数值大小没有影响,可用于简化运算。

截断数字

  • 直接截断高位。
  • 无符号数相当于取模(x%2^w = x')
  • 有符号数相当于转化为无符号数取模后,再转化为有符号数。

有符号数和无符号数之间的转换容易引起错误。详见习题。

整数运算

模数运算形成数学结构:阿贝尔群

无符号数运算和补码运算有完全相同的位级表示。

加法

无符号加法

正常情况x+y的值保持不变,溢出情况的结果是x+y-2^w

2-3.png

检测无符号加法的溢出:对于无符号数s=x+y,当且仅当s<x(等价地,s<y)时,发生溢出

补码加法

正常情况x+y的值不变,正溢出情况结果是x+y-2^w,负溢出情况结果是x+y+2^w

2-4.png

检测补码加法的溢出:对于补码s=x+y,当且仅当x<0,y<0,s≥0时,发生负溢出;当且仅当x>0,y>0,s≤0时,发生正溢出。

取非

得到取非结果的位级表示的方法:①按位取反后加一。②设k是最右边的1的位置,对k左边所有位取反即可。

无符号数

对于无符号数-x,x=0时结果是其本身,否则结果是2^w-x

补码

对于补码-x,x=TMin时结果是其本身,否则结果是-x

乘法

无符号数

x * y=(x * y) mod 2^w

补码

将结果位级表示转化为补码即可

乘以常数

与2的幂相乘

与2的k次幂相乘转化为左移k位实现。

与任意常数相乘

将常数K表示为0和1交替的二进制序列,将乘法运算转化为移位运算和加减法的组合。

设K的二进制表示中所有的1连续出现,且从位置n到位置m有连续的1

形式1:x * K = (x<<n )+ (x<<(n-1)) + ... + (x<<m)

形式2:x * K = (x<<(n+1)) - (x<<m)

不符合条件的情况可通过变换得到。

除以2的幂

无符号数

除以2的k次幂转化为右移k位实现,得到向下取整的结果。

补码

正数向下取整:除以2的k次幂转化为右移k位实现

负数向上取整:除以2的k次幂转化为,先加偏置量2^k-1=(1<<k)-1,后右移k位

  • 原理:
    \lceil x/y \rceil=\lfloor (x+y-1)/y \rfloor

“溢出”是针对码值转化为数值后,不符合直观运算规则而言的。但实际上码值运算规则无谓“溢出”,永远符合相同规则。如A+B=C就有C-B=A。

浮点数

二进制小数

IEEE浮点表示

V=(-1)^s*M*2^E

  • 符号s:0正1负

  • 尾数M:1 ~ 2-ε 或 0 ~ 1-ε

  • 阶码E

2-5.png
  • 符号位s编码符号s

  • k位阶码字段exp编码E

  • n位小数字段frac编码M

2-6.png
  • IEEE编码保证了从非规格化到规格化的平滑过渡
规格化

E=Exp-Bias

  • Exp是exp的无符号整数值
  • Bias=2^{k-1}-1
  • exp≠00…0且exp≠11…1
  • M=1.frac
非规格化

E=1-Bias

  • Bias=2^k-1
  • exp=00…0
  • M=0.frac
  • 用于表示0附近的小数值
特殊值
无穷大

exp=11...1,frac=00...0

NaN(Not-a-Number)

exp=11...1,frac≠00...0

舍入规则

  • 向偶数舍入:四舍六入五凑偶
  • 改变编码格式时,对于非规格化表示,先考虑能否转化为规格化保留精确度,否则再舍入
  • 其他舍入方式:向0舍入,向下舍入,向上舍入

浮点运算

加法
  • 满足交换律,不满足结合律
  • 除了无穷和NaN之外都有逆元
  • 符合单调性:若a≥b,则x+a≥x+b(a,b,x为除NaN之外的任意值)。无符号数和补码加法不符合单调性
乘法
  • 满足交换律,不满足结合律
  • 乘法对加法不满足分配律
  • 符合单调性:a≥b,若c≥0,则a * c ≥ b * c;若c≤0,则a * c ≤ b * c(a,b,c为除NaN之外的值)无符号数和补码乘法不符合单调性
  • a * a ≥ 0(a≠NaN)

类型转换

  • int -> float 不会溢出,但可能舍入
  • int/float -> double 不会溢出,保留精度
  • double -> float 可能溢出或者舍入
  • float/double -> int 向0舍入,或在无法确定整数近似值时(例如溢出)产生TMin

  1. 对于程序存储的管理完全是在虚拟地址空间中进行的。例如,指针指向的就是字节块的虚拟地址。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容