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) findint e1 = ~(x >> 31);int e2 = (~(x ^ e1));int x1 = e2;// example : 00001000 00000000   // two byteint 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 biteint 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 & 0int 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 00000000int dw = (uf & 0x7FFFFF) << 1;int j = uf & 0x7F800000;int jj = 0x800000;int f = uf & 0x80000000;if(!((j ^ 0x7F800000) << 1)){ // +- INFreturn 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 rangereturn 0x80000000u;}if(y < 0){//more than real result ,so require >>int ret = w >> -y;if(f){return -ret;}return ret;}//normal operationreturn (w << y) | f;
}
floatPower2

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

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

总结

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

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

过俩天学完下一章就开始下一个lab咯

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/68160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【【STM32-29正点原子版本串口发送传输实验】

STM32-29正点原子版本串口发送传输实验 通过串口接收或发送一个字符 例程目的 开发板上我们接入的是实现异步通信的UART接口 USB转串口原理图 我们一步步分析 PA9是串口1 的发送引脚 PA10是串口1 的接受引脚 。因为我们现在只是用到异步收发器功能&#xff0c;所以我们现…

qt中子窗口最小化后再恢复显示窗口区域显示为全白色

问题&#xff1a; qt中子窗口最小化后再恢复显示窗口区域显示为全白色&#xff0c;如下图&#xff1a; 原因&#xff1a; 恢复显示后窗口为及时刷新。 解决办法&#xff1a; 重写showEvent函数&#xff0c;如下&#xff1a; void MyClass::showEvent(QShowEvent *event) {se…

大模型 Dalle2 学习三部曲(二)clip学习

clip论文比较长48页&#xff0c;但是clip模型本身又比较简单&#xff0c;效果又奇好&#xff0c;正所谓大道至简&#xff0c;我们来学习一下clip论文中的一些技巧&#xff0c;可以让我们快速加深对clip模型的理解&#xff0c;以及大模型对推荐带来革命性的变化。 clip结构 首选…

Mybatis 动态SQL – 使用choose标签动态生成条件语句

之前我们介绍了if,where标签的使用&#xff1b;本篇我们需要在if,where标签的基础上介绍如何使用Mybatis提供的choose标签动态生成条件语句。 如果您对if,where标签动态生成条件语句不太了解&#xff0c;建议您先进行了解后再阅读本篇&#xff0c;可以参考&#xff1a; Mybat…

CSS中如何实现文字描边效果(Text Stroke)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 文字描边效果&#xff08;Text Stroke&#xff09;⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个…

Linux C语言 UDP协议实现的网络聊天室

需求分析 网络协议&#xff1a;UDP服务器需求&#xff1a; 需要一个存放用户数据的容器 因为是UDP协议&#xff0c;固采用链表的方式存储 服务器需要区分用户的操作类型&#xff08;如&#xff1a;上线&#xff0c;下线&#xff0c;发送消息&#xff09; 需要解析消息协议区分…

Navicat连接postgresql时出现‘datlastsysoid does not exist‘报错

当使用 Navicat 连接 PostgreSQL 数据库时出现 ‘datlastsysoid does not exist’ 的错误报错&#xff0c;这可能是由于 Navicat 版本与 PostgreSQL 版本不兼容所致。 这是因为在较新的 PostgreSQL 版本中移除了 ‘datlastsysoid’ 列&#xff0c;但可能较旧版本的 Navicat 尚…

Go实现LogCollect:海量日志收集系统【上篇——LogAgent实现】

Go实现LogCollect&#xff1a;海量日志收集系统【上篇——LogAgent实现】 下篇&#xff1a;Go实现LogCollect&#xff1a;海量日志收集系统【下篇——开发LogTransfer】 项目架构图&#xff1a; 0 项目背景与方案选择 背景 当公司发展的越来越大&#xff0c;业务越来越复杂…

Mysql底层数据结构为什么选择B+树

索引底层采用什么数据结构&#xff0c;为什么使用B树而不是其他数据结构&#xff1a; &#xff08;1&#xff09;如果采用二叉树&#xff1a;使用递增字段作为索引时&#xff0c;二叉树会退化成链表&#xff0c;查找效率太低 &#xff08;2&#xff09;如果采用红黑树&#xf…

微信小程序开发:一种新型的移动应用程序开发方式

一、引言 随着移动互联网的快速发展&#xff0c;微信小程序作为一种新型的移动应用开发方式&#xff0c;正在受到越来越多的关注。微信小程序是一种基于微信平台的轻量化应用&#xff0c;开发者可以通过微信提供的开发工具和接口&#xff0c;开发出各种具有特定功能的应用程序…

如何创建一个自己的sphinx文档网站

文章目录 前言一、操作步骤1.安装anaconda2.启动python3.8环境3.安装Sphinx4.创建文件夹5.初始化环境6. 编译7.文件夹搭查看8.搭建nginx查看8. 更换主题9.错误修复10.这里提供两个模板1.Demo_md2.Demo_rst前言 最近看到公司的文档中心,突然想起,为什么不为自己创建一个文档中…

在k8s中用label控制Pod部署到指定的node上

案例-标注k8s-node1是配置了SSD的节点 kubectl label node k8s-node1 disktypessd 查看标记 测试 将pod部署到disktypessd的节点上&#xff08;这里设置了k8s-node1为ssd&#xff09; 部署后查看结果-副本全都运行在了k8s-node1上—符合预期 删除标记 kubectl label node k8…

React常见知识点

1. setCount(10)与setCount(preCount > preCount 10) 的区别&#xff1a; import React, { useState } from react; export default function CounterHook() {const [count, setCount] useState(() > 10);console.log(CounterHook渲染);function handleBtnClick() {//…

顶尖211“小清华”!强过985,不要错过它!

一、学校及专业介绍 西安电子科技大学&#xff08;Xidian University&#xff09;&#xff0c;简称“西电” &#xff0c;位于陕西省西安市&#xff0c;是中央部属高校&#xff0c;直属于教育部&#xff0c;为全国重点大学&#xff0c;位列国家“双一流”“211工程”&#xff…

MySQL的内置函数复合查询内外连接

文章目录 内置函数时间函数字符串函数数学函数其他函数 复合查询多表笛卡尔积自连接在where中使用子查询多列子查询在from中使用子查询 内连接外连接左外连接右外连接 内置函数 时间函数 函数描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳…

Vagrant命令

文章目录 1.介绍2.下载3. 配置3.1 配置环境变量3.2 在xshell中连接使用 4. 相关命令4.1 Box相关4.2 初始化环境4.4 虚拟机相关 1.介绍 Vagrant 是一个虚拟机管理工具 2.下载 https://www.vagrantup.com/ 3. 配置 3.1 配置环境变量 测试安装是否成功 3.2 在xshell中连接使…

Linux权限维持

1.隐藏踪迹 创建隐藏文件(ls不可见&#xff0c;ls -la可见)&#xff1a; vim .shell.php修改时间戳(文件时间)&#xff1a; touch -r 老文件 shell.elf文件锁定(赋予特殊权限&#xff0c;不允许更改)&#xff1a; chattr i shell.elf无w、who、last等记录ssh&#xff1a; …

c#运算符重载

在C#中&#xff0c;您可以通过运算符重载来为自定义类型定义特定的操作行为。运算符重载允许您重新定义与特定运算符相关的操作&#xff0c;以便适应您自定义的类型。 以下是运算符重载的基本语法&#xff1a; public static <returnType> operator <operator> (…

模块化---common.js

入口文件&#xff1a;app.js // require是同步加载 // 客户端&#xff1a;common.js的模块化&#xff0c;需要browserify编译之后才能使用 // 服务端&#xff1a;运行时同步加载&#xff0c;无问题 let module1 require(./module1.js) let module2 require(./module2.js) co…

码云使用记录

码云使用记录 主要步骤 1、https://gitee.com 注册 2、下载Git 3、配置SSH 4、创建远程仓库 5、切到本地项目目录下将本地项目推到远程 前两步根据提示进行即可&#xff0c;下面从第三步开始讲解 3、配置SSH&#xff08;用于提交代码和更新代码&#xff09; https://gitee.…