西工大网络空间安全学院计算机系统基础实验一(45678)

接着来看第4个函数,int replaceByte(int x, int n, int c),看题目给出的例子,replaceByte(0x12345678,1,0xab) = 0x1234ab78。我们可以多写几个例子,进而找出规律,比如:

replaceByte(0x12345678,2,0xab) = 0x12ab5678

replaceByte(0x12345678,3,0xab) = 0xab345678

replaceByte(0x12345678,0,0xab) = 0x123456ab

replaceByte(0x12345678,1,0x00) = 0x12340078

由此我们猜测,返回值可能是(c<<(n<<3))|(~(0xFF<<(n<<3))&x),为什么呢?我们拿题目给的例子为例来讲。replaceByte(0x12345678,1,0xab) = 0x1234ab78,结果可以看成由0x0000ab00与0x12340078相或得到,那么该怎么得到0x0000ab00与0x12340078呢?发现0xab<<8即可得到0xab00,而0xab<<8 == 0xab<<(1<<3),进而发现可以通过(c<<(n<<3))得到0x0000ab00,接着如何得到0x12340078呢?发现0x12340078可由0x12345678&0xFFFF00FF得到,而x即为0x12345678,那么该如何得到0xFFFF00FF呢?发现0xFFFF00FF==~0x0000FF00,而0x0000FF00==0xFF<<(1<<3),即0xFF<<(n<<3)。所以综上所述,我们得到了(c<<(n<<3))|(~(0xFF<<(n<<3))&x),下面我们使用Python进行检验,如(图1:第4个函数——用Python验证想法)所示。经过Python验证,我们的想法是正确的,接着我们重复第1、2、3个函数的流程,使用VS code修改bits.c文件,使用"./dlc bits.c"与"./dlc -e bits.c"命令确保第4个函数中使用的运算符等满足要求,使用"make clean", "make btest"函数编译生成新的btest可执行文件,使用"./btest -f replaceByte"命令保证函数能产生正确的结果。如(图2:第4个函数)所示,成功编写第4个函数。

另外,发现第4个函数还可以再次修改,使得使用到的运算符再少一个,如(图3:优化后的第4个函数)所示。

**************************************************************************************************************

(图1:第4个函数——用Python验证想法)

************************************************************************************************************** 

**************************************************************************************************************

(图2:第4个函数)

**************************************************************************************************************

**************************************************************************************************************

 

(图3:优化后的第4个函数)

**************************************************************************************************************

接着看第5个函数,int mult3div2(int x), 看题目给出的三个例子:mult3div2(11) = 16; mult3div2(-9) = -13; mult3div2(1073741824) = -536870912(overflow)。先看第一个例子,mult3div2(11) = 16,11的十六进制形式为0xB, (0xB<<1)+0xB可以得到0x21,接着0x21>>1得到0x1,十进制形式为16,正好是第一个例子的结果。虽然如此,我们依然可以留心到0x21右移一位时,最低位的1被移走了,但是歪打正着,正好满足了向0舍入的要求。所以我们猜测,返回的表达式是((x<<1)+x)>>1。第二个例子,mult3div2(-9) = -13,-9的16进制形式为0xFFFF FFF7,((0xFFFF FFF7)<<1)+(0xFFFF FFF7)可以得到0xFFFF FFE5,接着0xFFFF FFE5>>1得到0xFFFF FFF2,十进制形式为-14。但是期望中的结果是-13,而不是-14。这时我们发现,0xFFFF FFE5右移一位时,最低位的1被移走了,而且与向0舍入背道而驰。第三个例子,mult3div2(1073741824) = -536870912(overflow),1073741824的十六进制形式为0x4000 0000,(0x4000 0000<<1)+0x4000 0000可以得到0xC000 0000,0xC000 0000>>1得到0xE000 000,十进制形式即为-536,870,912,正好是答案的形式。

现在整理一下,只有当(x<<1)+x的最低位为1,并且x的最高位也为1时,返回的结果需要在((x<<1)+x)>>1的基础上,再多加1,否则不需要加1,直接返回((x<<1)+x)>>1即可。但是,真的是这样子嘛???作者私底下偷偷试过几次,发现还需要添加一条附加条件:(x<<1)+x的最高位也为1。那么如何用表达式表示出来“(x<<1)+x的最低位为1、最高位为1,并且x的最高位也为1”呢?((((x<<1)+x)<<31)&((x<<1)+x)&x)>>31。因为(x<<1)+x被反复使用,所以为了节省运算符,我们选择设置temp=(x<<1)+x,这样子即可写作:((temp<<31)&temp&x)>>31。只有当(x<<1)+x的最低位为1,最高位为1,并且x的最高位也为1时,((temp<<31)&temp&x)>>31的结果为0xFFFFFFFF,否则即为0。注意!!!在这里千万不要简单的将((x<<1)+x)>>1与((temp<<31)&temp&x)>>31相加!!!应该将((temp<<31)&temp&x)>>31取反后加1,即~(((temp<<31)&temp&x)>>31)+1,然后再与((x<<1)+x)>>1相加,才是正确的表达式子。作者就是因为这个错误,改了好一会。仿照着第1、2、3、4个函数的方法,我们来检验我们的函数对不对。如(图4:第5个函数)所示。

最后,至于为什么要添加那一条,作者并不清楚,等以后有时间慢慢研究吧。

**************************************************************************************************************

(图4:第5个函数)

**************************************************************************************************************

第6个函数,int multFiveEighths(int x) ,执行效果应该类似于C语言中的x*5/8,而且向0舍入。这道题比第5题的难度更大。但我们不妨采用类似的方法,先确定大概的轮廓((x<<2)+x)>>3,接着再去细调。而细调的方法是,不断比较对于不同的x,两个表达式((x<<2)+x)>>3与x*5/8的值是否会有不同,以及会有多大的不同。观察发现似乎对于0到2147483647的正整数来说,((x<<2)+x)>>3与x*5/8的值相同,对于-1到-2147483648的负数来说,除非该负数能够整除8,否则 x*5/8=(((x<<2)+x)>>3)+1。而如果x这个负数能够整除8,则x<<29为0x0,并且x>>31=0xFFFF FFFF,写在一起即为(x>>31)&!(x<<29)。所以最终返回的表达式是:(((x<<2)+x)>>3)+((x>>31)&!!(x<<29))(注意这里采用了两个取非符号!!!这个地方很容易错)。仿照第1、2、3、4、5个函数的方法,我们来检验第6个函数的正确性,如(图5:第6个函数)所示。

**************************************************************************************************************

(图5:第6个函数)

**************************************************************************************************************

第7个函数,int addOK(int x, int y),判断x+y是否会发生溢出。如果会发生溢出,那么返回0,如果不会发生溢出,则返回1。而两个int类型变量相加会造成溢出的情况是:当两个正数相加得到的结果为负数,或者两个负数相加得到的结果为正数时,就会发生溢出。用"int sum=x+y"来保存x+y的值。返回!((~((x>>31)^(y>>31)))&((x>>31)^(sum>>31)))。虽然最终通过了,如(图6:第7个函数)所示,但是其中的函数逻辑并没有理清楚,还需要进行一轮又一轮的迭代与优化。

**************************************************************************************************************

(图6:第7个函数)

**************************************************************************************************************

第8个函数,int bitCount(int x),返回int型变量x的十六进制表示形式中1的个数。比如当x=5时,5为0x0101,有2个1,当x=7时,7为0x0111,有3个1。这道题比较复杂,使用到了“汉明重量”的知识。作者结合Java中对于函数bitCount的实现方法,简单修改了下代码,使其满足对于运算符等的要求,之后按照前7个函数相同的方法,写完了第8个函数,如(图7:第8个函数)所示:

**************************************************************************************************************

(图7:第8个函数)

**************************************************************************************************************

最后,45678这8个函数的代码如(图8:5个函数的C语言源代码)所示:

**************************************************************************************************************

int replaceByte(int x, int n, int c) {int temp = n<<3; return (c<<temp)|(~(0xFF<<temp)&x);
}
int mult3div2(int x) {int temp=(x<<1)+x; return (temp>>1)+(~(((temp<<31)&temp&x)>>31)+1);
}
int multFiveEighths(int x) {return (((x<<2)+x)>>3)+((x>>31)&!!(x<<29));
}
int addOK(int x, int y) {int sum=x+y;return !((~((x>>31)^(y>>31)))&((x>>31)^(sum>>31)));
}
int bitCount(int x) {int temp1 = 0x55|(0x55<<8)|(0x55<<16)|(0x55<<24);int temp2 = 0x33|(0x33<<8)|(0x33<<16)|(0x33<<24);int temp3 = 0xf|(0xf<<8)|(0xf<<16)|(0xf<<24);int n = x + ~((x >> 1) & temp1) + 1;n = (n & temp2) + ((n >> 2) & temp2);n = (n + (n >> 4)) & temp3;n = n + (n >> 8);n = n + (n >> 16);return n & 0x3f;
}

(图8:5个函数的C语言源代码)

**************************************************************************************************************

 

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

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

相关文章

SASS的导入文件详细教程

文章目录 前言导入SASS文件使用SASS部分文件默认变量值嵌套导入原生的CSS导入后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Sass和Less &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努…

使用Terraform创建Docker镜像和容器

为了实现自动化操作&#xff0c;Terraform需要明确指定所使用的提供者。因此&#xff0c;在主要的main.tf文件中&#xff0c;需要提供提供者的名称、源和版本信息。对于Docker&#xff0c;可以在main.tf中使用以下代码块。 1 Terraform配置模块 使用块和资源创建Terraform脚本…

每日一题:LeetCode-202.面试题 08.06. 汉诺塔问题

每日一题系列&#xff08;day 07&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

QT搭建的Ros/librviz的GUI软件

1.前言 开发初期学习了下面博主的文章&#xff0c;也报了他在古月局的课&#xff0c;相当于感谢吧。 ROS Qt5 librviz人机交互界面开发一&#xff08;配置QT环境&#xff09;-CSDN博客​​​​​​​r 软件前期也是参考他的开源项目 GitHub - chengyangkj/Ros_Qt5_Gui_App …

Java核心知识点整理大全22-笔记

目录 19.1.14. CAP 一致性&#xff08;C&#xff09;&#xff1a; 可用性&#xff08;A&#xff09;&#xff1a; 分区容忍性&#xff08;P&#xff09;&#xff1a; 20. 一致性算法 20.1.1. Paxos Paxos 三种角色&#xff1a;Proposer&#xff0c;Acceptor&#xff0c;L…

【SpringBoot3+Vue3】五【完】【实战篇】-前端(配合后端)

目录 一、环境准备 1、创建Vue工程 2、安装依赖 2.1 安装项目所需要的vue依赖 2.2 安装element-plus依赖 2.2.1 安装 2.2.2 项目导入element-plus 2.3 安装axios依赖 2.4 安装sass依赖 3、目录调整 3.1 删除部分默认目录下文件 3.1.1 src/components下自动生成的…

GO 集成Prometheus

一、Prometheus介绍 Prometheus&#xff08;普罗米修斯&#xff09;是一套开源的监控&报警&时间序列数据库的组合&#xff0c;起始是由SoundCloud公司开发的。随着发展&#xff0c;越来越多公司和组织接受采用Prometheus&#xff0c;社会也十分活跃&#xff0c;他们便…

re:Invent 2023:PingCAP 荣获亚马逊云科技 2023 年度合作伙伴奖项

2023 年 11 月 27 日 – 12 月 1 日&#xff0c; 2023 亚马逊云科技 re:Invent 在拉斯维加斯举办&#xff0c;亚马逊云科技合作伙伴奖项在合作伙伴颁奖晚会上颁布&#xff0c; PingCAP 荣获亚马逊云科技大中华区 “2023 年度 ISV 合作伙伴” 和 “2023 年度亚马逊云科技 Market…

离散时间信号的分析(数字信号处理实验1-2)

前言&#xff1a;该系列实验均使用matlab完成&#xff0c;实验课程为《数字信号处理》 文章目录 一.题目二.实验目的三.实验仪器四.实验原理实验所用的matlab函数解析离散时间信号实验原理&#xff1a; 五.实验步骤六.实验代码及实验结果完整代码1.线性卷积代码2.循环卷积运算…

WordPress 外链跳转插件

WordPress 外链跳转插件是本站开发的一款WordPress插件&#xff0c;能对文中外链添加一层过滤&#xff0c;有效防止追踪&#xff0c;以及提醒用户。 类似于知乎、CSDN打开其他链接的提示。 后台可以设置白名单 学习资料源代码&#xff1a;百度网盘 密码&#xff1a;123

前端已死?看看我的秋招上岸历程

背景 求职方向&#xff1a;web前端 技术栈&#xff1a;vue2、springboot&#xff08;学校开过课&#xff0c;简单的学习过&#xff09; 实习经历&#xff1a;两段&#xff0c;但都是实训类的&#xff0c;说白了就是类似培训&#xff0c;每次面试官问起时我也会坦诚交代&…

蓝桥杯每日一题2023.11.28

题目描述 三羊献瑞 - 蓝桥云课 (lanqiao.cn) 题目分析 本题首先进行观察可以确定 1.“三”为 1 &#xff08;十进制数字要进位进一位&#xff09; 2.“祥”一定不为 0 &#xff08;有前导0就不能算为 4 位数&#xff09; 使用搜索时将其特判 #include<bits/stdc.h> …

SparkRDD及算子-python版

RDD相关知识 RDD介绍 RDD 是Spark的核心抽象&#xff0c;即 弹性分布式数据集&#xff08;residenta distributed dataset&#xff09;。代表一个不可变&#xff0c;可分区&#xff0c;里面元素可并行计算的集合。其具有数据流模型的特点&#xff1a;自动容错&#xff0c;位置…

蓝桥杯day02——移动机器人

1.题目 有一些机器人分布在一条无限长的数轴上&#xff0c;他们初始坐标用一个下标从 0 开始的整数数组 nums 表示。当你给机器人下达命令时&#xff0c;它们以每秒钟一单位的速度开始移动。 给你一个字符串 s &#xff0c;每个字符按顺序分别表示每个机器人移动的方向。L 表…

《opencv实用探索·四》Mat图像数据类型转换和归一化显示

一种数据类型转为另一种数据类型&#xff0c;不改变图像大小&#xff0c;但每个像素值可能会变 src.convertTo(dst, type, scale, shift);Scale和shitf默认为0&#xff08;这两个参数也相当于对比度和亮度&#xff09; 现在有个8位图像&#xff0c;把8位转成32位 可以看到像素…

基于SSM的仓库管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

JS 倒计时方法(可改造)

起因&#xff1a; 写好备用。 代码&#xff1a; // 直接把方法写在了原型上&#xff0c;通过原型调用 /*** 倒计时* time_str String 到期时间(2023-11-28 16:50:00)* dom_obj Object 需要显示的倒计时的dom对象*/ Date.prototype.countdown function (time_str, dom_obj…

JAVA小游戏简易版王者荣耀

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 GameFrame 运行类 package com.sxt; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;…

【企业微信连接问题】

1、个人可以创建企业微信的企业账号么&#xff1f; 答&#xff1a;可以的&#xff0c;只是没法认证。不过基础的功能还是有的。 注册步骤&#xff1a;企业微信注册步骤 2、集简云链接企业微信&#xff0c;在授权之后&#xff0c;找不到集简云怎么办&#xff1f; 答&#xff1a…

CSS特效021:蛇形左右扭动的效果

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…