20145214 《信息安全系统设计基础》第3周学习总结

教材学习内容总结

信息的表示和处理

  • 二进制数字称为位(bit)
  • 三种重要的数字表示:无符号编码、补码(有符号)、浮点数(科学计数法)

信息的存储

  • gcc -m32 可以在64位机上(比如实验楼的环境)生成32位的代码

  • 最低有效字节在最前面的方式,称为小端法;最高有效字节在最前面的方式,称为大端法。即小端是“高对高、低对低”,大端与之相反

  • P28代码加上main函数后执行如下

  • 逻辑运算结果是0和1,位运算结果是位向量

  • 掩码是位运算的重要应用,对特定位可以置一,可以清零

整数表示

  • 补码的利用寄存器的长度是固定的特性简化数学运算。想想钟表,12-1 等价于 12 + 11,利用补码可以把数学运算统一成加法,只要一个加法器就可以实现所有的数学运算
  • 如果有任何一个运算数是无符号的,那么在比较之前,另一个运算数会被强制转换为无符号数
  • 将一个无符号数转换为一个更大的数据类型,我们只需要简单的在表示的开头添加0,这种运算成为零扩展
  • 将一个补码数字转换为一个更大的数据类型可以执行符号扩展,规则是在表示中添加最高有效位的值的副本

整数运算

  • 练习题2.27:写出函数——如果参数x和参数y相加不会产生溢出,这个函数就返回1

  • 计算机执行的“整数”运算实际上是一种模运算形式

浮点数

  • IEEE标准754

  • IEEE浮点标准用V = (-1)^s × M × 2^E的形式来表示一个数:

      符号:s决定这个数是负数(s=1)还是正数(s=0),而对于数值0的符号位解释作为特殊情况处理。
      尾数:M是一个二进制小数,它的范围是1~2-ε,或者是0~1-ε。
      阶码:E的作用是对浮点数加权,这个权重是2的E次幂(可能是负数)。
    
  • 将浮点数的位表示划分为三个字段,分别对这些值进行编码:

      一个单独的符号位s直接编码符号s。
      k位的阶码字段exp = ek-1…e1e0编码阶码E。
      n位小数字段frac = fn-1…f1 f0编码尾数M,但是编码出来的值也依赖于阶码字段的值是否等于0。
    

习题练习中的问题和解决过程

练习题2.11

  • 加上main函数后执行,发现数组长度为奇数时,中间的元素会被置为0

  • 由于在最后一次调用inplace_swap的时候,y指向的数字就变为了0。解决办法只需要将reverse_array函数的循环条件中的first<=last 改为first<last(最中间的数字不会参与循环)即可。

  • 注意修改过后需要再次编译才能显示正确的结果!

练习题2.25

  • 按照原代码会出现错误
  • 改正代码的方法:一是将length声明为int类型;二是将for循环的测试条件改为 i < length

练习题2.42

  • 测试代码时结果出现错误

  • 进入vi检查代码,查不出明显的错误

  • 目前尚未解决问题

家庭作业

2.61

  • 按照题目要求,A选项应为 !(x+1);B选项应为 !x;C选项应为 !((x & (0xFF << ((sizeof(int)-1) << 3))) + (1 << ((sizeof(int)-1) << 3)));D选项应为 !(x & 0xFF)

  • 代码如下

      void main(void)
      {
         int x;
         int w = sizeof(int) << 3 /* A. x=111...111 */
         printf("x=111...111 return 1\n");
         x = ~0;
         printf("!(0x%X+1): %s\n", x, !(x+1) ? "right" : "wrong");
         x = 0xFFFFFFFE;
         printf("!(0x%X+1): %s\n", x, !(x+1) ? "right" : "wrong"); /* B. x=000...000 */
         printf("x=000...000 return 1\n");
         x = 0;
         printf("!0x%X: %s\n", x, !x ? "right" : "wrong");
         x = 1;
         printf("!0x%X: %s\n", x, !x ? "right" : "wrong");  /* C. 1111 1111 0101 ... 0101 */
         printf("x=_1111 1111_else return 1\n");
         x = 0xFF123456;
         printf("(0x%X & (0xFF << ((sizeof(int)-1) << 3))) + (1 << ((sizeof(int)-1) << 3)): %s\n",
                 x, !((x & (0xFF << (w-8))) + (1 << (w-8))) ? "right" : "wrong");
    
       
        x = 0xEFFFFFFF;
         
        printf("(0x%X & (0xFF << ((sizeof(int)-1) << 3))) + (1 << ((sizeof(int)-1) << 3)): %s\n",
                 x, !((x & (0xFF << (w-8))) + (1 << (w-8))) ? "right" : "wrong");
       /* D. 1010 0101 ... 0000 0000 */
        printf("x=else..._0000 0000_ return 1\n");
        x = 0x12345600;
        printf("!(0x%X & 0xFF): %s\n", x, !(x & 0xFF) ? "right" : "wrong");
        x = 0x12345601;
        printf("!(0x%X & 0xFF): %s\n", x, !(x & 0xFF) ? "right" : "wrong");
      }
    
  • 运行结果如下

代码托管情况

代码托管链接(http://git.oschina.net/20145214/znn20145214)

代码托管截图

代码行数统计

其他(感悟、思考等,可选)

  • 本周的学习在老师给的重点练习的习题上开始,从遇到的习题开始往回看公式,现在能够套着公式一步一步计算得出结果,但是公式太多了容易混淆。
  • 课本上的代码也有许多需要自己再构造的部分,虽然大致知道思路如何,但是代码调试出现问题的时候总是首先会对自己构造的部分产生怀疑,最后查不出问题所在很崩溃...

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第零周 0/0 1/1 5/5 使用虚拟机安装linux系统,安装ubuntu
第一周 100/100 1/2 20/25 掌握核心的linux命令,了解了linux操作系统
第二周 76/176 1/3 30/55 学会了虚拟机上的C编程
第三周 214/390 1/4 20/75 初步学习计算机中各种数的表示和运算

参考资料

Copyright © 2024 20145214张宁
Powered by .NET 8.0 on Kubernetes