• 20155212 ch02 课下作业


    20155212 ch02 课下作业

    T1

    • 题目

      参考附图代码,编写一个程序 “week0601学号.c",判断一下你的电脑是大端还是小端

    • 相关知识

      • 小端法:最低有效字节在最前面
      • 大端法:最高字节在最前面
    • 思路

      • 将参数的指针强制类型转换为unsigned char *代码利用强制转换类型告诉机器,程序应该把这个指针看成指向一个字节序列,而不是指向一个原始数据类型的对象。然后这个指针会被看成是对象使用的最低字节地址。
    • 代码

    #include <stdio.h>
    
    typedef unsigned char *byte_pointer;
    
    void show_bytes(byte_pointer start, size_t len) {
    	size_t i;
    	for(i=0; i<len; i++)
    		printf(" %.2x", start[i]);
    	printf("
    ");
    }
    
    void show_int(int x) {
    	show_bytes((byte_pointer) &x, sizeof(int));20155212 ch02 课下作业
    }
    
    void show_float(float x) {
    	show_bytes((byte_pointer) &x, sizeof(float));
    }
    
    void show_pointer(void  *x) {
    	show_bytes((byte_pointer) &x, sizeof(void *));
    }
    
    void test_show_bytes(int val) {
    	int ival=val;
    	float fval=(float)ival;
    	int *pval=&ival;
    	show_int(ival);
    	show_float(fval);
    	show_pointer(pval);
    }
    
    void main() {
    	int val;
    	scanf("%d", &val);
    	test_show_bytes(val);
    }
    
    • 运行结果

    • 结果分析

      参数12345的十六进制表示应该是0x00003039,但是实际显示最低有效字节0x39最先输出,说明这是小端机器。

    T2

    • 题目
      1. 调用附图代码,编写一个程序 “week0602学号.c",用show_int(), show_float()打印一下你的4位学号,参考教材P33打印出匹配的位序列
      2. 参考教材p82,给出出匹配的位序列的推导过程
    • 相关知识
      • 如何输出位序列。(代码如下)
    int i, j;
    for(i=0; i<11; i++)
    	printf(" ");
    for(i=0; i<len; i++){
    	for(j=0; j<8; j++){
    		printf("%d", (start[i]>>j) & 0x1);
    	}
    }
    printf("
    ");
    
    - IEEE浮点表示
    

    • 代码
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef unsigned char *byte_pointer;
    
    void show_bytes(byte_pointer start, size_t len) {
    	size_t i;
    	for(i=0; i<len; i++)
    		printf(" %.2x", start[i]);
    	printf("
    ");
    }
    
    void show_int(int x) {
    	size_t len=sizeof(int);
    	show_bytes((byte_pointer) &x, len);
    	byte_pointer start=(byte_pointer) &x;
    	int i, j;
    	for(i=0; i<11; i++)
    		printf(" ");
    	for(i=0; i<len; i++){
    		for(j=0; j<8; j++){
    			printf("%d", (start[i]>>j) & 0x1);
    		}
    	}
    	printf("
    ");
    }
    
    void show_float(float x) {
    	size_t len=sizeof(float);
    	show_bytes((byte_pointer) &x, len);
    	byte_pointer start=(byte_pointer) &x;
    	int i, j;
    	for(i=0; i<len; i++){
    		for(j=0; j<8; j++){
    			printf("%d", (start[i]>>j) & 0x1);
    		}
    	}
    	printf("
    ");
    }
    
    void show_pointer(void  *x) {
    	show_bytes((byte_pointer) &x, sizeof(void *));
    }
    
    void test_show_bytes(int val) {
    	int ival=val;
    	float fval=(float)ival;
    	int *pval=&ival;
    	show_int(ival);
    	int i;
    	for(i=0;i<11;i++){
    		printf(" ");
    	}
    	for(i=0;i<13;i++)
    		printf("*");
    	printf("
    ");
    	show_float(fval);
    }
    
    void main() {
    	int val;
    	scanf("%d", &val);
    	test_show_bytes(val);
    }
    
    • 运行结果

    • 推导

      5212具有二进制表示[1010001011100],将二进制小数点左移13位,得到规格化表示1.010001011100 x 2^13。为了用IEEE单精度形式编码,舍弃开头的1,并在末尾增加10个0,来构造小数字段,得到二进制表示[10100010111000000000000]。为了构造阶码字段,用13加上偏置量127,得到140,其二进制表示为[10001100],加上符号位0,即可得到二进制的浮点表示[01000101101000101110000000000000]。

    T3

    • 题目

      1. 编写一个程序 “week0603学号.c",运行下面代码:

        1  short int v = -学号后四位
        2  unsigned short uv = (unsigned short) v
        3  printf("v = %d,  uv = %u
         ", v, uv);
        
      2. 在第三行设置断点用gdb调试,用p /x v; p /x uv 查看变量的值,提交调试结果截图,要全屏,要包含自己的学号信息

      3. 分析p /x v; p /x uv 与程序运行结果的不同和联系

    • 相关知识

      • 有符号和无符号数之间的转换
        • C语言允许在各种不同的数字数据类型之间做强制类型转换。
        • 强制类型转换的结果保持位值不变,只是改变了解释这些位的方式。
      • gdb调试
        • b (line number):设置行断点
        • run:运行
        • p:print
        • /x:十六进制
    • 代码

    #include<stdio.h>
    
    void main(){
    	short int v = -5212;
    	unsigned short uv = (unsigned short) v;
    	printf("v = %d,  uv = %u
     ", v, uv);
    }
    
    • 运行结果

    • 分析

      数值可能会改变,但是位模式不变

    P97 2.96

    • 题目
    • 相关知识
      - IEEE浮点表示
    • 代码
    #include <stdio.h>
    
    typedef unsigned float_bits;
    
    int float_f2i(float_bits f){
        unsigned sign, exp, frac, last_bit;
        int i;
        sign = f >> 31;
        exp = (f >> 23) & 0xff;
        frac = f & 0x7fffff;
        if (exp == 158 && frac == 0 && sign == 1)
            i = 0x80000000;
        else if (exp > 157 || exp == 0xff)
            i = 0x80000000;
        else if (exp < 126)
            i = 0;
        else{
            exp -= 127;
            frac |= 0x800000;
            if (exp > 23){
                exp -= 23;
                frac <<= exp;
            }else if (exp < 23){
                exp = 23 - exp;
                frac >>= exp;
            }
            if (sign == 1)
                i = (~frac) + 1;
            else
                i = frac;
        }
        return i;
    }
    void main(){
    	float f;
        unsigned i;
        int j, k;
        
        for (i = 0x3fbfff70U; i <= 0xffffffffU; i++)
        {
            f = *(float *)&i;
            j = (int)f;
            k = float_f2i(i);
            printf("原值:%f 	 机器运算:%d 	 函数运算:%d
    ", f, j, k);
        }
    }
    
    • 运行结果

    P97 2.97

    • 题目
    • 代码
    #include <stdio.h>
    
    typedef unsigned float_bits;
    typedef unsigned char *byte_pointer;
    
    void show_bytes(byte_pointer start, size_t len) {
    	size_t i;
    	for(i=0; i<len; i++)
    		printf(" %.2x", start[i]);
    	printf("	");
    }
    
    float_bits float_i2f(int x) {
    	unsigned shiftLeft=0;  
    	unsigned afterShift, tmp, flag;  
    	unsigned absX=x;  
        unsigned sign=0;  
        if (x==0) 
        	return 0;  
        if (x<0){  
            sign=0x80000000;  
            absX=-x;  
        }  
        afterShift=absX;  
        while (1){
        	tmp=afterShift;
        	afterShift<<=1;
        	shiftLeft++;  
    		if (tmp & 0x80000000) 
    			break;  
        }
        if ((afterShift & 0x01ff)>0x0100)  
    		flag=1;  
        else if ((afterShift & 0x03ff)==0x0300)  
    		flag=1;  
        else  
    		flag=0;  
    	return sign+(afterShift>>9)+((159-shiftLeft)<<23)+flag;
    }
    
    
    void main(){
        int x;
        unsigned i,k;
        float j;
    
        for (i = 0x3fbfff70U; i <= 0xffffffffU; i++){
            x = *(int *)&i;
            printf("原值:");
            show_bytes((byte_pointer) &x, sizeof(int));
            j=(float)i;
            printf("机器运算:");
            show_bytes((byte_pointer) &j, sizeof(float));
            k=float_i2f(i);
            printf("函数运算:");
            show_bytes((byte_pointer) &k, sizeof(unsigned));
            printf("
    ");
        }
    }
    
    
    • 运行结果
  • 相关阅读:
    lua pbc
    c保存lua函数
    c语言的lua库编写
    Gridcontrol新增行选中有关问题
    python3 练习题100例 (十五)
    python3 练习题100例 (十四)
    python3 练习题100例 (十三)
    python3 练习题100例 (十二)
    python3 练习题100例 (十一)
    python3 练习题100例 (十)
  • 原文地址:https://www.cnblogs.com/dky20155212/p/7751945.html
Copyright © 2020-2023  润新知