zoukankan      html  css  js  c++  java
  • 信息的表示和处理学习记录

    重要知识点

    三种数字表示

    1. 无符号:编码基于传统的二进制表示法,表示大于或等于0的数字。
    2. 补码:编码表示有符号整数的最常见的方式,有符号整数就是可以为正或者为负的数字。
    3. 浮点数:编码是表示实数的科学记数法的以二为基数的版本。

    漏洞原因:因为3种数字精度有限所以计算机会因溢出而使用求模运算,使无限的明文对应有限的密文,因此会出现漏洞。

    进制转换

    在计算机导论课程中已掌握。

    32位与64位机器中的数据大小

    C声明

    32位机器

    64位机器

    char

    1

    1

    short int

    2

    2

    int

    4

    4

    long int

    4

    8

    long long int

    8

    8

    char *

    4

    8

    float

    4

    4

    double

    8

    8

    用gcc –m32可以在64位机上生成·32位代码

    寻址和字节顺序

    小端法:在存储器中按照从最低有效字节到最高有效字节的顺序存储对象,"高对高,低对低"。

    大端法:在存储器中按照从最高有效字节到最低有效字节的顺序存储。"高对低,低对高"。

    布尔代数

    在离散数学中已掌握。

    掩码

    我们能通过指定一个位向量掩码,有选择地使能或是不能屏蔽一些信号,其中某一位位置上为1时,表明信号i是有效的,而0表明该信号是屏蔽的。因此,这个掩码表示的就是设置为有效信号的集合。掩码运算通常是通过位级运算来实现的。

    逻辑运算和位级运算

    C语言中提供了一组逻辑运算符||、&&和!,分别对应于命题逻辑中的OR、AND和NOT运算。逻辑运算很容易和位级运算相混淆,但是它们的功能是完全不同的·。逻辑运算认为所有非零的参数都表示TRUE,而参数0表示FALSE。它们返回1或者0,分别表示结果为TRUE或者FALSE。

    按位运算只有在特殊情况下,也就是参数被限制为0或者1时,才和·与其对应的逻辑运算有相同的行为。

    逻辑运算符&&和||与它们对应的位级运算&和|之间第二个重要的区别是,如果对第一个参数求值就能确定表达式的结果,那么逻辑运算符就不会对第二个参数求值。

    移位运算

    C语言还提供了一组移位运算,以便向左或向右移动位模式。移位运算可以从左向右结合的,所以x<<j<<k等价于(x<<j)<<k。

    一般而言,机器支持两种形式的右移:逻辑右移和算数右移。逻辑右移在最左端补k个0,算数右移在最左端补k各最高有效位的值。

    C语言标准没有明确定义应该使用哪种类型的右移。对于无符号数据,右移必须是逻辑的。对于有符号数据,算数的或者逻辑的右移都可以。

    使用C99标准编译long long类型

    C源文件代码

    编译及运行命令·

    C语言中有符号数和无符号数的转换

    位向量不变,只是上下文的读取方式不同,所以根据不同的读取规则,最终的读取结果也不同。这就是所谓的信息就是位+上下文。

    注:c语言中要创建一个无符号常量,必须加上后缀字符'U'或者'u'。

        转换的原则是底层的位表示保持不变。

    怎么让负数等于正数

        将有符号负数转化为无符号正数,变的只是上下文的读取方式,但二进制位级表示是一样的。

    零扩展和符号扩展

    零扩展:将一个无符号数转换为一个更大的数据类型,我们只需要简单地在开头添加0。

    符号扩展:将一个补码数字转换为一个更大的数据类型,规则是在表示中添加最高有效位的值的副本。

    无符号数与有符号数容易造成的错误

    例:以下一段代码

    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是无符号的,计算0-1将进行无符号运算,这等价于模数加法。结果得到UMax。<=比较进行同样使用无符号数比较,而因为任何数都是小于或者等于UMax的,所以这个比较总是为真!因此,代码将试图访问数组a的非法元素。

    改正方法:1.将length声明为int类型。

    2.或将for循环的测试条件改为i<length。

    整数溢出

    整数溢出:指完整的整数结果不能放到数据类型限制的字长中去。

    避免整数溢出:当两个整数进行运算时,其结果用更大的数据类型进行存储。比如两个int类型的整数相乘的结果用long long数据类型的变量来存储。

    关于整数运算的思考

    计算机执行的"整数"运算实际上是一种模运算形式。表示数字的有限字长限制了可能的值的取值范围,结果运算可能溢出。

    补码提供了一种既能表示负数也能表示正数的灵活方法,同时使用了与执行无符号算数相同的位级实现,这些运算包括加减乘除,无论是以无符号形式还是以补码形式表示的,都有完全一样或者非常类似的位级行为。

    浮点数

    浮点表示对形如V=x*的有理数进行编码。它对涉及非常大的数字(|    V|>>0)、非常接近于0(|V|<<1)的数字,以及更普遍地作为实数运算的近似值的计算,是很有用的。

    浮点数的运算及执行标准:IEEE标准754。

    浮点数运算的不精确性和舍入

        当一个数字不能精确地表示为IEEE标准754时,就必须向上或者向下调整,此时出现舍入。

    IEEE浮点标准,float和double类型p70

        单精度浮点格式(float)中,s、exp和frac字段分别为1位、k=8位和n=23位,得到一个32位的表示。

        双精度浮点格式(double)中,s、exp和frac字段分别为1位、k=11位和n=52位,得到一个64位的表示。

    整数与浮点数转换规则

    当在int、float和double格式之间进行强制类型转换时,程序改变数值和位模式的原则如下(假设int是32位的):

    1. 从int转换成float,数字不会溢出,但是可能被舍入。
    2. 从int或float转换成double,因为double有更大的范围(也就是可表示值的范围),也有更高的精度(也就是有效位数),所以能够保留精确的数值。
    3. 从double转换成float,因为范围要小一些,所以值可能溢出为+∞或-∞。另外由于精确度较小,它还可能被舍入。
    4. 从float或者double转换为int,值将会向零舍入。

    重点练习

    1. p24进制转换代码

      十进制转十六进制

      源文件代码

       

      运行命令

       

      十六进制转十进制

      源文件代码

      运行命令

     

    2.p28 show_bytes,写个main函数测试一下

    源文件代码

    运行结果

    3.练习2.11用GDB单步跟踪

    源代码

    gdb单步跟踪

     

    4.p44 代码放到一个main函数中

    源文件代码

    运行结果

     

    5.p47/p49代码放到一个main函数中运行。

         p47源代码

    运行结果

    p49源代码

    运行结果

        

    6.p78转换规则可以写几行代码试试

    源代码

    运行结果

    遇到问题

    在运行perl语言文件是遇到如下错误

    解决办法

    网上查资料解决。

    Linux下perl文件的执行

    #! /usr/bin/perl

    第一个"#"表示是这一行是注释

    第二个"!"表示这一行不是普通注释,而是解释器路径的声明行

    解释器的路径可以通过locate perl找到。

    例子:

    #!/usr/bin/perl

    #test.pl

    print "test message! \n";

    然后,给文件加上可执行的属性:

    $ chmod 755 test.pl 或者 $ chmod +x test.pl

    这两个命令用哪一个都可以。

    现在执行吧: $ ./test.pl

    作业中的运行命令如作业图所示。

     

    课后练习

    2.66

    题目:创建一个函数leftmost_one(unsigned x),实现将x除最高有效位1外其他位全部置为0的功能,如果最高有效位为0则返回0。

    要求:1.遵循位级整数编码规则。

       2.代码中最多只能包含15个算术运算、位运算和逻辑运算。

    思路:1.若x为001xxxxxx则将其与xx100000想于即可得到所求结果。

       2.若想得到xx100000则可通过或运算将001xxxxx转化为00111111,将其取反后为11000000,右移一位可得01100000。

       3.将x与01100000相与即可得到所求结果00100000。

    函数代码:

    运行结果:

    2.68

    题目:构建函数int lower_bits(int n)将int 变量的低n位置1,其余位置0。

    思路:将~0左移n位与-1异或可得结果。

    函数代码:

    运行结果:

  • 相关阅读:
    Otter详解
    为什么要使用Netty
    haproxy实现mysql集群负载均衡
    Mysql主从复制
    java编程思想读书笔记三(HashMap详解)
    代码界的石器时代
    补码的产生与应用
    java编程思想读书笔记二(对象的创建)
    java编程思想读书笔记一(面向对象)
    Apache VFS
  • 原文地址:https://www.cnblogs.com/Ntime/p/4853874.html
Copyright © 2011-2022 走看看