CSAPP lab1 Data Lab

这篇具有很好参考价值的文章主要介绍了CSAPP lab1 Data Lab。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

CSAPP lab1-Data Lab

前言:

本系列文章用于记录开始学习csapp的过程,奈何感觉自己基础实在太渣渣,系统好好学习一下这本神书以及其对应的lab

lab

这一张的lab是真的干,好几道题卡的我脑壳都卡秃噜了,好歹终于凭借着面向用例编程完成了这一张的lab

Btest tests your code for correctness by running millions of test
cases on each function.  It tests wide swaths around well known corner
cases such as Tmin and zero for integer puzzles, and zero, inf, and
the boundary between denormalized and normalized numbers for floating
point puzzles. When btest detects an error in one of your functions,
it prints out the test that failed, the incorrect result, and the
expected result, and then terminates the testing for that function.

很多很多测试用例哦,再也不用担心绞尽脑子想测试用例拉

简介

本实验分为俩部分,第一部分是对整数操作,第二部分是对浮点数操作。

通过可以使用的运算符来实现出要求的操作即可,并且通过./dlc -e bits.c 来检测自己是否使用非法操作

完成后可通过./btest 查看自己分数,以及对应是哪个测试用例错误

题目

bitXor

只使用 & 和 ~ 实现 ^ 上手题还是很轻松的啦

int bitXor(int x, int y) {
    int t1 = x & y;
    int t2 = ~x & ~y;
    return ~t1 & ~t2;
}
tmin

按照定义给出最小值就可以了,0x80000000

int tmin(void) {
  return 1 << 31;
}
isTmax

我这里用的是如果是最大值那么*2 +就是0xFFFFFFFE(最后一位是0其他全1),然后+2就是0了然后取反是1,同时看看x不是-2就行了

int isTmax(int x) {
    int p = x + 2 + x ;
    return !p & (!!(x + 1));
}
allOddBits

如果所有奇数位设置为1,则返回1. 这个我直接就是用一个奇数位全1的去和x进行与操作,如果是正确的话,那么e2取反也就是偶数位全1,在和他们与的结果取或结果一定是-1,反之其他的都不对。上述很多思路就是根据唯一满足的找特定关系,那么其他就几乎是不满足的。

int allOddBits(int x) {
    int e = (0xAA << 8) + 0xAA;
    int e2 = (e << 16) + e;
    int p = e2 & x;
    return !((~e2 | p) + 1);
}
negate

这个直接按照定义就可以,取反+1

int negate(int x) {
  return ~x + 1;
}
isAsciiDigit

这个是判断一个数是否在一个区间里。

我的方法就是把公式变换一下,譬如 [x <= 0x39 ]-> [ x - 0x39 <= 0 ] -> [x - 0x39 - 1] < 0

因为减法可以模拟,然后和0比较的值又可以用符号位判断

int isAsciiDigit(int x) {
    int p1 = 0x30;
    int d1 = ~p1 + 1;

    int p2 = 0x39 + 1;
    int d2 = ~p2  + 1;

    int e1 = !((x + d1) >> 31);
    int e2 = (x + d2) >> 31;
    return e1 & e2;
}
conditional

实现一个 x ? y : z 运算

我直接就将x 变成要么全1要么全0,然后都与完+在一起了

int conditional(int x, int y, int z) {
    int e = !!x;
    int e2 = (e << 31) >> 31;
    int e3 = ~e2;
    return (e2 & y) + (e3 & z);
}
isLessOrEqual

判断x <= y

用分类思想,然后找特殊关系就可以。反正也只有4中情况 【正,正】 【负,负】,【正,负】,【负,正】

后面俩种情况直接就能得出结果,然后讨论前面的就行,也不用考虑溢出了

int isLessOrEqual(int x, int y) {
    int f1 = x >> 31 & 1;
    int f2 = y >> 31 & 1;
    int e = ~(y) + 1;
    int e3 = x + e;
    int e4 = e3 >> 31 & 1;
    int e1 = (f1 ^ 0) & (f2 ^ 1);
    int e2 = !((f1 ^ 1) & (f2 ^ 0));
    return e2 & (e1 | e4 | !(x ^ y));
}
logicalNeg

这个是取逻辑非,从这里开始就我就卡起来了(当时没搞明白定义)。

思想还是从特殊的数出手,只有0能返回1,其他就都是0了

int logicalNeg(int x) {
    int e1 = ((x) >> 31) ^ 1;
    int e2 = (x + ~0) >> 31;
    return e1 & e2 & 1;
}
howManyBits

这个上来就是个王炸,想着怎么也不能这么写吧,想半天不会其他的只能模拟了。

目的是找到最低用多少位就能表示这个数,其实就是从左到又找到第一个与左边不一样的数字,他的位置就是那个返回数(这个变变形状,负数正数就统一了)

所以最后的问题就变成,找最左边第一个出现的1的位置

然后我就想了好久啊~,最终被迫使出我的二分大法(伪二分,一开始凭感觉写的,最后优化了一下发现超就没改了)

基本上就是分段,然后求最左边第一个出现1的段,其他的段就扔了

思路很简单,用这些操作符真是嘎嘎写

int howManyBits(int x) { // pretend bisection(binary) find
    int e1 = ~(x >> 31);
    int e2 = (~(x ^ e1));
    int x1 = e2;
    // example : 00001000 00000000   // two byte
    int d1 = x1 & 0xFF;//0+
    int x2 = x1 >> 8;
    int d2 = x2 & 0xFF;//8+
    int x3 = x2 >> 8;
    int d3 = x3 & 0xFF;//16+
    int x4 = x3 >> 8;
    int d4 = x4 & 0xFF; // 24+

    int d4f = ((!!d4 << 31) >>31);
    int p10 = d4f & 24;
    int p11 = p10 + ((!p10 << 31) >> 31 & ((!d3 << 4) ^ 16 ));
    int p12 = p11 + ((!p11 << 31) >> 31 & ((!d2 << 3) ^ 8 ));
    int p1 = p12;
    //p1 = (!p1 << 31) >> 31 & ((!!d1 << 31) >> 31 ) & 0;

    // get have 1 byte that high 8 bite
    int b1 = d4f & d4;
    int b2 = (((!b1 << 31) >> 31) & d3) | b1;
    int b3 = (((!b2 << 31) >> 31) & d2) | b2;
    int b4 = (((!b3 << 31) >> 31) & d1) | b3;
    int b = b4;

    int d5 = b & 0xF; //0+
    int bb = b >> 4;
    int d6 = bb & 0xF;//4+

    int d6f = ((!!d6 << 31) >>31);
    int p2 = d6f &  4;
    //p2 = (!p2 << 31) >> 31 & (!!d1 << 31) >> 31 & 0

    int b5 = d6f & d6;
    int b6 = (((!b5 << 31) >> 31) & d5) | b5;

    int p30 = (b6 >> 1) & 4;
    int p31 = p30 + ((!p30 << 31) >> 31 & (((b6 & 4) << 29) >> 31) & 3);
    int p32 = p31 + ((!p31 << 31) >> 31 & b6 & 2);
    int p33 = p32 + ((!p32 << 31) >> 31 & b6 & 1);
    int p3 = p33;

    return p1 + p2 + p3 + 1;
}
floatScale2

经过上面的洗礼,下面这个稍稍简单一点点。

搞清楚规格书和非规格数的表示形式就行了

unsigned floatScale2(unsigned uf) {
    // 32 bite 0 0000000 0 0000000 00000000 00000000
    int dw = (uf & 0x7FFFFF) << 1;
    int j = uf & 0x7F800000;
    int jj = 0x800000;
    int f = uf & 0x80000000;
    if(!((j ^ 0x7F800000) << 1)){ // +- INF
        return uf;
    }
    if( !j && !!(dw & 0x800000) ){ // exponent is zero that represent 非规格化
        j += jj;
        dw &= 0x7FFFFFFF;
    } else if(j){
        j += jj;
        dw >>= 1;
    }
    return f | dw | j;
}
floatFloat2Int

这个就是float转int,搞清楚边界情况(书上都有),用if else秒了他,这if else一解封,上面浮点数格式搞清楚,洒洒水啦~

int floatFloat2Int(unsigned uf) {
    int w = (uf & 0x7FFFFF )| 0x800000;
    int j = (uf & 0x7F800000) >> 23;
    int f = uf & 0x80000000;
    int p = j - 126;
    int y = p - 24;
    if(!j || (p & 0x80000000)){// 非规格化,且为0 或者是太小的数
        return 0;
    }
    if(((p - 31) >> 31) == 0){ // out range
        return 0x80000000u;
    }
    if(y < 0){//more than real result ,so require >>
        int ret = w >> -y;
        if(f){
            return -ret;
        }
        return ret;
    }
    //normal operation
    return (w << y) | f;
}
floatPower2

这个嘛~,自行理解了,更简单了

unsigned floatPower2(int x) {
    if(x <= -127){
        return 0;
    }
    if(x >= 128){
        return 0x7f800000;
    }
    return (x + 127) << 23;
}

总结

写完啦,这俩天脑袋全是二进制数了,倒是对我的算法上使用这些位操作更熟练了,也同时理解了之前没学到位的浮点数。

日常写完去看看别人怎么写的,一看,撕~,我擦看不懂,全是符号巴拉巴拉的,遂放弃,写此篇。

过俩天学完下一章就开始下一个lab咯文章来源地址https://www.toymoban.com/news/detail-694473.html

到了这里,关于CSAPP lab1 Data Lab的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL数据库操作 Lab1

    掌握MySQL安装、配置与登录方法,使用MySQL客户创建数据库及对数据库表完成各种操作 1、安装MySQL数据库管理系统,5.7.X(建议5.7.23及以上)或8.X版本都可以。客户端不限。 2、使用MySQL客户端创建数据库,并且在库中按照设计创建数据库表,并把数据插入各表中。 1、学习并掌

    2024年02月08日
    浏览(33)
  • 北京大学计算机网络lab1——MyFTP

    目录 Lab目标 一、知识补充 二、具体实现 1.数据报文格式和字符串处理 2.open函数 3.auth 4.ls 5.get和put 三、总结 ps:本人靠着计网lab几乎就足够在就业行情并不好的23年找到自己满意的工作了,计网lab的教程也非常给力,对我这种恐惧写lab的菜狗都非常友好(本人写lab3确实比较

    2024年02月07日
    浏览(54)
  • CSAPP Lab4- PerfLab

    图像用一维数组表示,第(i,j)个像素表示为I[RIDX(i,j,n)],n为图像的维数 目标:使用代码优化技术使旋转操作运行的更快 目标:使用代码优化技术使平滑操作运行的更快 CPE or Cycles per Element 如果一个函数使用C个周期去执行一个大小为N*N的图像,那么CPE=C/(N*N),因此CPE越小越好

    2024年02月06日
    浏览(43)
  • CSAPP Shell Lab 实验报告

    前言:强烈建议先看完csapp第八章再做此实验,完整的tsh.c代码贴在文章末尾了 进程的概念、状态以及控制进程的几个函数(fork,waitpid,execve)。 信号的概念,会编写正确安全的信号处理程序。 shell的概念,理解shell程序是如何利用进程管理和信号去执行一个命令行语句。 sh

    2024年02月04日
    浏览(41)
  • CS144 计算机网络 Lab1:Stream Reassembler

    上一篇博客中我们完成了 Lab0,使用双端队列实现了一个字节流类 ByteStream ,可以向字节流中写入数据并按写入顺序读出数据。由于网络环境的变化,发送端滑动窗口内的数据包到达接收端时可能失序,所以接收端收到数据之后不能直接写入 ByteStream 中,而是应该缓存下来并

    2023年04月20日
    浏览(38)
  • MIT6.5830 Lab1-GoDB实验记录(四)

    标签:Golang 读写缓冲区我是一点思路都没有,所以得单独开篇文章记录。 实验补充 了解buffer、序列化与反序列化 这里的序列化,简单来说类似于把一个很长的字符串拆成一个个字符;反序列化就是把这一个个字符拼回成完整的字符串。此处我们需要根据所给的Tuple,转换为

    2024年02月06日
    浏览(51)
  • MIT6.5830 Lab1-GoDB实验记录(五)

    完成了Exercise 1,还有四个Exercise在等着我,慢慢来吧。 实验准备 了解缓冲池 缓冲池,俗称BP。相关的概念还有数据页和缓存页。页(Pages)的概念和操作系统中“分页”的概念是一样的,指的都是把逻辑地址空间分为若干同等大小的页,并从0开始编号。 而缓冲池(Buffer Po

    2024年02月05日
    浏览(47)
  • 哈工大csapp-LAB3程序优化

    实验报告 实 验(三) 题     目       优化                 专       业     人工智能(未来技术)     学    号    7203610716              班    级    20WJ102                学       生     孙铭蔚             指 导 教 师     刘宏伟

    2023年04月24日
    浏览(45)
  • CSAPP cache lab - Optimizing Matrix Transpose

    矩阵转置是一种操作,它将矩阵的行和列互换位置,即将原始矩阵的行变为转置矩阵的列,将原始矩阵的列变为转置矩阵的行。转置操作可以通过改变矩阵的布局来方便地进行某些计算和分析。 假设有一个m×n的矩阵A,其转置矩阵为n×m的矩阵B。那么B的第i行第j列的元素就是

    2024年01月22日
    浏览(40)
  • MIT6.S081 - Lab1: Xv6 and Unix utilities

    可以参考 user/echo.c , user/grep.c 和 user/rm.c 文件 如果用户忘记传递参数, sleep 应该打印一条错误消息 命令行参数传递时为字符串,可以使用 atoi 函数将字符串转为数字 使用系统调用 sleep ,有关实现 sleep 系统调用的内核代码参考 kernel/sysproc.c (查找 sys_sleep ),关于可以从用户程序

    2024年04月16日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包