20155212 ch02 课下作业

20155212 ch02 课下作业

T1

  • 题目

    参考附图代码,编写一个程序 “week0601学号.c",判断一下你的电脑是大端还是小端
    1043723-20171029121237539-349379980.png
  • 相关知识
    • 小端法:最低有效字节在最前面
    • 大端法:最高字节在最前面
  • 思路
    • 将参数的指针强制类型转换为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("\n");
}

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);
}
  • 运行结果
    1043723-20171029121949258-1346743858.png
  • 结果分析

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

T2

  • 题目
    1. 调用附图代码,编写一个程序 “week0602学号.c",用show_int(), show_float()打印一下你的4位学号,参考教材P33打印出匹配的位序列
      1043723-20171029122454508-801961562.png
    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("\n");
- IEEE浮点表示

1043723-20171029140756867-1820514559.png

  • 代码
#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("\n");
}

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("\n");
}

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("\n");
}

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("\n");
    show_float(fval);
}

void main() {
    int val;
    scanf("%d", &val);
    test_show_bytes(val);
}
  • 运行结果
    1043723-20171029134208211-101791191.png
  • 推导

    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\n ", 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\n ", v, uv);
}
  • 运行结果
    1043723-20171029153326961-1670835427.png
  • 分析

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

P97 2.96

  • 题目
    1043723-20171029153806476-305356845.png
  • 相关知识
    - IEEE浮点表示
    1043723-20171029140756867-1820514559.png
  • 代码
#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 \t 机器运算:%d \t 函数运算:%d\n", f, j, k);
    }
}
  • 运行结果
    1043723-20171029163634320-541588417.png

P97 2.97

  • 题目
    1043723-20171029154028023-1182806568.png
  • 代码
#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("\t");
}

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("\n");
    }
}
  • 运行结果
    1043723-20171029180540930-303290412.png

转载于:https://www.cnblogs.com/dky20155212/p/7751945.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值