20155212 ch02 课下作业

时间:2023-03-10 06:20:51
20155212 ch02 课下作业

20155212 ch02 课下作业

T1

  • 题目

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

    20155212 ch02 课下作业

  • 相关知识

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

    • 将参数的指针强制类型转换为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);
}
  • 运行结果

    20155212 ch02 课下作业

  • 结果分析

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

T2

  • 题目
    1. 调用附图代码,编写一个程序 “week0602学号.c",用show_int(), show_float()打印一下你的4位学号,参考教材P33打印出匹配的位序列

      20155212 ch02 课下作业
    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浮点表示

20155212 ch02 课下作业

  • 代码
#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);
}
  • 运行结果

    20155212 ch02 课下作业

  • 推导

    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);
}
  • 运行结果

    20155212 ch02 课下作业

  • 分析

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

P97 2.96

  • 题目

    20155212 ch02 课下作业
  • 相关知识

    - IEEE浮点表示

    20155212 ch02 课下作业
  • 代码
#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);
}
}
  • 运行结果

    20155212 ch02 课下作业

P97 2.97

  • 题目

    20155212 ch02 课下作业
  • 代码
#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");
}
}
  • 运行结果

    20155212 ch02 课下作业