西工大计算机学院计算机系统基础实验一(函数编写11~14)

稳住心态不要慌,如果考试周冲突的话,可以直接复制这篇博客和上一篇博客西工大计算机学院计算机系统基础实验一(函数编写1~10)-CSDN博客最后的代码,然后直接提交,等熬过考试周之后回过头再慢慢做也可以。

第11个函数,rempwr2,要求计算x%(2^n),其中0<=n<=30。比如rempwr2(15,2) = 3, rempwr2(-35,3) = -3。什么意思呢?意思是15%(2^2)=15%4=3,-35%(2^3)=-35%8=-3。那么我们该怎么做呢?先考虑正数,当x为15并且n为2时,15可写作1111B,15%(2^2)即相当于取1111B的低2个比特位,即11B,正如答案中的3。接着考虑负数,-35可写作0xFFFF FFFF FFFF FFDD,-3可写作0xFFFF FFFF FFFF FFFD,如果像处理正数那样直接截取0xFFFF FFFF FFFF FFDD的第3个比特位的话,得到的应该是101B,也就是5,而不是-3,所以负数不能像正数那样被处理。最简单的方法是分类讨论,但是那样会使用蛮多的运算符,所以尝试使用一种新的思路去处理这个问题。我们可不可以这样子,先计算35%(2^3)=3,然后再把3变为-3呢?也就是说,先把一个数变成它自己的绝对值,然后参与%运算,最后再根据最开始这个数的符号位调整最终的结果呢?按照这个思路,我们首先将x变成它的绝对值,可以通过(x+(x>>31))^(x>>31)来实现,当为正时,(x+(x>>31))^(x>>31)的结果仍为x,当x为负数时,比如x=-35=0xFFFF FFDD,那么x>>31=0xFFFF FFFF,x+(x>>31)的结果是0xFFFF FFDE,接着0xFFFF FFDE与0xFFFF FFFF异或,得到了0x0000 0023,也就是35。(当x为负数时,+(x>>31)相当于-1,接着与x>>31异或相当于全取反,就是根据负数原码求补码的逆过程,只不过考虑到表达式(x+(x>>31))^(x>>31)也综合了x是正数的情况,所以不方便直白的写减一后全取反)接着当n=2时如何产生0000... ...0011,当n=3时如何产生0000... ...0111呢?可以通过(~0)+(1<<n)来产生。~0为0xFFFF FFFF,当n=3时,1<<3为0x8,~0+(1<<3)即得到了0x0000 0007。这时让((x+(x>>31))^(x>>31))与~0+(1<<n)进行位与操作,即可完成%操作。此时若x是正数,则所有步骤已完成,但是当x为负数时,还需要将最后的结果加一个负号。怎么加负号呢?各位取反加1,先与x>>31做异或操作完成各位取反,最后减去x>>31完成加1。结合上述的讲解,我们给出代码,如 图1:编写第11个函数rempwr2 所示。接着仿照前10个函数相同的检查流程,如 图2:检查第11个函数rempwr2 所示。

int s = x>>31;
x = (x+s)^s;
x &= ((~0)+(1<<n));
return (x^s)+~s+1;

图1:编写第11个函数rempwr2

图2:检查第11个函数rempwr2

 第12个函数,satMul2,执行算术乘法乘2。怎么做呢?如果x为小于0x4000 0000的正数,或者为0,或者为大于C000 0000的负数,那么直接返回x<<1即可。而当x超出这个范围时,就不能直接返回x<<1了。那如何判断什么时候可以直接返回x<<1,什么时候不能直接返回x<<1呢?发现可以引入变量int x2=x<<1,x2表示x*2,再引入变量int sx2=(x2)>>31表示x*2的符号位,一旦x的符号位与x<<1的符号位不相同,即(x^x2)>>31的结果为0xFFFF FFFF时,就不能直接返回x<<1,而如果x的符号位与x<<1的符号位相同,即(x^x2)>>31的结果为0x0时,就可以直接返回x<<1,所以可以引入变量int flag=(x^x2)>>31,并以此作为判断条件。根据已有的知识,可以写出下面的大框架:

(flag&(                ))  |  (~flag&(      x2          ))

接着,如果x的符号位与x<<1的符号位不相同,即(x^x2)>>31的结果为0xFFFF FFFF,不能直接返回x<<1时,该返回什么呢?易知此时只需返回0x8000 0000或者0x7FFF FFFF。该如何得知该返回0x8000 0000还是该返回0x7FFF FFFF呢?发现这时当x为很大的正数,并且x2的符号位为1时,sx2为0xFFFF FFFF,加上0x8000 0000之后即为0x7FFF FFFF,即应该返回的值;当x为很小的负数,并且x2的符号位为0时,sx2为0x0000 0000,加上0x8000 0000之后即为0x8000 0000,即应该返回的值。而0x8000 0000可写作1<<31。根据这个分析,我们进一步完善大框架:

(flag&(      sx2+(1<<31)          ))  |  (~flag&(      x2          ))

这时再思考,能不能想办法进行优化以减少运算符使用的个数呢?发现当flag为0xFFFF FFFF时,(~flag&(      x2          )中的x2不一定一定为0;当~flag为0xFFFF FFFF时,(flag&(      sx2+(1<<31)          ))中的sx2+(1<<31)也不一定一定为0,所以不能像第9个函数那样进行优化。因此,第12题最终的代码为如 图3:编写第12个函数satMul2 所示。

  int x2=x<<1;int sx2=x2>>31;int flag=(x^x2)>>31;int tmin=1<<31;return ((~flag&x2)+(flag&(sx2+tmin)));

(图3:编写第12个函数satMul2)

然而这道题似乎有问题。为什么呢?其实只要简单的"return x<<1"就能通过!白白耗费我们这么多时间。如 图4:检查第12个函数satMul2 所示。

 (图4:检查第12个函数satMul2

第13个函数,subOK,如果x减去y的值能被int类型大小的变量装得下,就返回1,否则返回0。接着我们发现,当x与y同号时,不可能出现装不下也就是溢出的问题,只有当x与y异号时,才可能会用装不下也就是溢出的问题,顺着这个思路,我们可以分成两类来讨论。而分类的依据则是x^~y,当x与y同号时,x^~y的符号位为1,当x与y异号时,x^~y的符号位为0。顺着这个思路,写出下面的大框架:

((    (x^~y)&(            )    |    ( ~(x^~y)&(             )    )   ) >>31)&1

当x与y同号时,x与~y异号,x^~y的符号位为1,此时x减去y的值一定能被int类型大小的变量装得下,所以此时返回1即可。这时大框架即为:

((    (x^~y)                    |    (  ~(x^~y)&(             )    )   ) >>31)&1

而当x与y异号时,x与~y同号,x^~y的符号位为0,此时如果x与x-y=x+~y+1异号,那么必定发生了溢出,x减去y的值一定不能被int类型大小的变量装得下,所以选择表达式~(x^(x+~y+1)),当x与x-y同号时,说明可以装得下,应该返回1,而~(x^(x+~y+1))的符号位恰好就是1;当当x与x-y异号时,说明不可以装得下,应该返回0,而~(x^(x+~y+1))的符号位恰好就是0。所以最终的大框架即为:

((    (x^~y)                    |    (  ~(x^~y)&(     ~(x^(x+~y+1))        )    )   ) >>31)&1

代码如 图5:编写第13个函数subOK 所示。检查过程如 图6:检查第13个函数subOK 所示。

  int flag=x^~y;return ((flag|(~flag&(~(x^(x+~y+1)))))>>31)&1;

图5:编写第13个函数subOK

图6:检查第13个函数subOK) 

第14个函数,float_twice,在这里限制被释放,条件判断可以被使用,while语句也可以被使用,||和&&也可以被使用,而且也可以创建unsigned型的局部变量。那么这个函数要求我们做到什么呢?这个函数要求我们,对于一个浮点数f,计算2*f。举个例子来讲,如果f=0.625,那么其在计算机内部的表示形式为0x3F20 0000,计算2*f可以得到0x3FA0 0000,而这个0x3FA0 0000就是期待我们返回的值。对不起大家,在这里作者实在有点累了,所以没办法今天就讲完了。代码如 图7:编写第14个函数float_twice 所示。检查第14个函数的过程如 图8:检查第14个函数float_twice 所示

  unsigned sign = 0, enow = 0, fnow = 0;unsigned pos = 1 << 31;unsigned frule = (1 << 23) - 1;if (uf == 0) {return 0;}if (uf == pos) {return uf;}sign = uf & pos;enow = (uf >> 23) & 0xff;if (enow == 0xff) {return uf;}fnow = uf & frule;if (enow == 0) {fnow = fnow << 1;if (fnow & (1 << 23)) {fnow = fnow & frule;enow += 1;}}else{enow += 1;}return sign | (enow << 23) | fnow;

图7:编写第14个函数float_twice

 

图8:检查第14个函数float_twice

/* * rempwr2 - Compute x%(2^n), for 0 <= n <= 30*   Negative arguments should yield negative remainders*   Examples: rempwr2(15,2) = 3, rempwr2(-35,3) = -3*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 20*   Rating: 3*/
int rempwr2(int x, int n) {int s = x>>31;x = (x+s)^s;x &= ((~0)+(1<<n));return (x^s)+~s+1;
}
/** satMul2 - multiplies by 2, saturating to Tmin or Tmax if overflow*   Examples: satMul2(0x30000000) = 0x60000000*             satMul2(0x40000000) = 0x7FFFFFFF (saturate to TMax)*             satMul2(0x80034000) = 0x80000000 (saturate to TMin)*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 20*   Rating: 3*/
int satMul2(int x) {// int x2=x<<1;// int sx2=x2>>31;// int flag=(x^x2)>>31;// int tmin=1<<31;return x<<1;// return ((~flag&x2)+(flag&(~(!!x2)+1)&(sx2+tmin)));// int isx2zero=!x2;// int x2notzero=!isx2zero;// return ((~flag&x2)+(flag&(~(!!x2)+1)&(~x2notzero&(sx2+tmin))));// int istmin=!(x^tmin);// return ((istmin<<31)|((~istmin)&((~flag&x2)|(flag&(sx2+tmin)))));
}
/* * subOK - Determine if can compute x-y without overflow*   Example: subOK(0x80000000,0x80000000) = 1,*            subOK(0x80000000,0x70000000) = 0, *   Legal ops: ! ~ & ^ | + << >>*   Max ops: 20*   Rating: 3*/
int subOK(int x, int y) {int flag=x^~y;return ((flag|(~flag&(~(x^(x+~y+1)))))>>31)&1;
}
/* * float_twice - Return bit-level equivalent of expression 2*f for*   floating point argument f.*   Both the argument and result are passed as unsigned int's, but*   they are to be interpreted as the bit-level representation of*   single-precision floating point values.*   When argument is NaN, return argument*   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while*   Max ops: 30*   Rating: 4*/
unsigned float_twice(unsigned uf) {unsigned sign = 0, enow = 0, fnow = 0;unsigned pos = 1 << 31;unsigned frule = (1 << 23) - 1;if (uf == 0) {return 0;}if (uf == pos) {return uf;}sign = uf & pos;enow = (uf >> 23) & 0xff;if (enow == 0xff) {return uf;}fnow = uf & frule;if (enow == 0) {fnow = fnow << 1;if (fnow & (1 << 23)) {fnow = fnow & frule;enow += 1;}}else{enow += 1;}return sign | (enow << 23) | fnow;
}

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

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

相关文章

如何做好软文推广的选题?媒介盒子分享常见套路

选题是软文推广的重中之重&#xff0c;主题选得好&#xff0c;不仅能够戳到用户&#xff0c;提高转化率&#xff0c;还能让各位运营的写作效率大幅度提升&#xff0c;今天媒介盒子就来和大家分享软文选题的常见套路&#xff0c;助力各位品牌进行选题。 一、 根据产品选题 软文…

【AI-Fix】解决地图展示包leafmap在Jupyter NoteBook中地图不显示的问题

1. 问题描述 新创建的环境想使用leafmap在Jupyter中进行地图展示&#xff0c;结果发现运行完成之后不显示&#xff0c;不论怎么重启都没有办法显示出来&#xff0c;以经验来看&#xff0c;多半是缺了包了。 于是去leafmap的官方文档查找原因&#xff0c;一开始并没有发现什么问…

C++ 拷贝构造函数

目录 拷贝构造函数概述 拷贝构造函数特性 拷贝构造函数概述 当我们定义好一个类&#xff0c;不做任何处理时&#xff0c;编译器会自动生成以下6个默认成员函数&#xff1a; 默认成员函数&#xff1a;如果用户没有手动实现&#xff0c;则编译器会自动生成的成员函数。 同样&…

JavaWeb(十)

一、JavaWeb概述 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www)&#xff0c;能够通过浏览器访问的网站。 JavaWeb&#xff1a;使用 Java技术进行web互联网开发。 二、JavaWeb 技术栈 2.1、B/S 架构 B/S 架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器…

解决找不到msvcr120.dll无法执行代码的4个方法,快来看看解决方法!

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“缺少xxx.dll文件”。而msvcr120.dll就是其中之一。那么&#xff0c;msvcr120.dll到底是什么呢&#xff1f;它又有什么作用呢&#xff1f;本文将从多个方面对msvcr120.dll进行详细的解析…

华为鸿蒙爆发真实力!原生应用媲美iOS,使用流畅度将提升20至30%

随着华为鸿蒙原生应用开发计划的启动&#xff0c;一场席卷全球的科技浪潮正在涌动。鸿蒙生态的快速发展&#xff0c;吸引了无数企业和开发者的关注&#xff0c;他们纷纷拥抱这个新兴的生态系统&#xff0c;共同构建一个更加繁荣的鸿蒙世界。 华为鸿蒙原生应用开发计划引爆全球…

【电路笔记】-交流电路中的电阻器

交流电路中的电阻器 文章目录 交流电路中的电阻器1、概述2、交流电路中的电阻器示例 13、交流电路中的电阻器示例2 电阻器也可用于交流电源&#xff0c;其中消耗的电压、电流和功率以有效值给出。 1、概述 在之前的文章中&#xff0c;我们研究了电阻器及其连接&#xff0c;并使…

Leetcode刷题笔记题解(C++):BM11 链表相加(二)

思路&#xff1a;先对两个链表进行反转&#xff0c;反转求和注意进位运算&#xff0c;求和完成之后再进行反转得到结果 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ #include <cstddef> class Soluti…

Excel 删除空白行

目录 一. 方式一: 筛选删除二. 方式二: 定位条件三. 方式三: 隐藏非空白行&#xff0c;删除空白行 一. 方式一: 筛选删除 选中空白行对应的列&#xff0c;按下Ctrl Shift L&#xff0c;给列添加过滤条件。过滤出空白行&#xff0c;然后删除即可。 二. 方式二: 定位条件 按下…

【Qt】QLineEdit显示输入十六进制,位数不足时按照规则填充显示及每两个字符以空格填充

问题 在实际开发中&#xff0c;有时候需要对输入进行限制&#xff0c;一是更加合理&#xff0c;二是防止出现误操作。 比如&#xff1a; 使用Qt进行应用程序开发时&#xff0c;对单行编辑框QLineEdit控件&#xff0c;设置只可输入十六进制。 限制输入的方式常用且经典的是使用…

Linux常用指令详解

目录 前言&#xff1a; Linux的目录结构 Linux常用指令简介 whoami指令 ls指令 pwd指令 cd指令 tree指令 touch指令 mkdir指令 rmdir指令与rm指令 man指令 cp&#xff08;copy&#xff09;指令 mv&#xff08;move&#xff09;指令 cat指令 重定向及重定向的类型…

Redis——某马点评day03——part2:秒杀业务异步优化

异步秒杀思路 原本的流程是如下所示&#xff0c;必须从开始到创建订单成功才会返回响应。就像饭店里面从下单到上菜都是一个人在服务&#xff0c;就导致服务员利用率很低&#xff0c;后一个顾客要等到前一个顾客上完菜才可以下单。 最简单的优化就是加员工&#xff0c;一次性…

6.1810: Operating System Engineering 2023 <Lab3: page tables>

一、本节任务 实验环境&#xff1a; 二、要点 如何防止程序破坏内核或其他进程空间&#xff1f;隔离地址空间&#xff0c;进程只能读写自己的内存空间。 在保证隔离的同时&#xff0c;如何将多个地址空间复用到一个物理内存上&#xff1f;虚拟内存/页表。操作系统通过页表来为…

DDSP-SVC-3.0完全指南:一步步教你用AI声音开启音乐之旅

本教程教你怎么使用工具训练数据集推理出你想要转换的声音音频&#xff0c;并且教你处理剪辑伴奏和训练后的音频合并一起&#xff0c;快来试试看把&#xff01; 1.使用的工具 要想训练ai声音&#xff0c;首先需要有各种工具&#xff0c;还需要我们提供你需要训练的声音&#…

Avalonia中如何将View事件映射到ViewModel层

前言 前面的文章里面我们有介绍在Wpf中如何在View层将事件映射到ViewModel层的文章&#xff0c;传送门&#xff0c;既然WPF和Avalonia是两套不同的前端框架&#xff0c;那么WPF里面实现模式肯定在这边就用不了&#xff0c;本篇我们将分享一下如何在Avalonia前端框架下面将事件…

陀螺仪LSM6DSV16X与AI集成(2)----姿态解算

陀螺仪LSM6DSV16X与AI集成.2--姿态解算 概述视频教学样品申请完整代码下载欧拉角万向节死锁四元数法姿态解算双环PI控制器偏航角陀螺仪解析代码上位机通讯加速度演示陀螺仪工作方式主程序演示 概述 LSM6DSV16X包含三轴陀螺仪与三轴加速度计。 姿态有多种数学表示方式&#xff…

多人聊天室

多人聊天包 由于要先创建服务面板&#xff0c;接收客户端连接的信息&#xff0c;此代码使用顺序为先启动服务端&#xff0c;在启动客户端&#xff0c;服务端不用关&#xff0c;不然会报错。多运行几次客户端&#xff0c;实现单人聊天 1.创建服务面板 package yiduiy;import j…

【计算机二级MS Office】word(上)

这里写目录标题 文件选项卡保存和另存为属性检查文档 开始选项卡字体更改字体和字号设置中文和英文为两种不同字体的快捷方式介绍其余图标文本效果突出颜色如何挑选字体颜色字符底纹带圈字符字体对话框&#xff08;隐藏&#xff09; 段落 插入选项卡设计选项卡布局选项卡引用选…

【头歌系统数据库实验】实验6 SQL的多表查询-2

目录 第1关&#xff1a;查询每个选手的信息及其提交的解答信息&#xff0c;没做题的选手不显示 第2关&#xff1a;查询做了1001题且耗时大于500&#xff08;time&#xff09;的选手信息 第3关&#xff1a;查询所有选手信息及其提交的解答信息&#xff0c;没做题的选手也要显…

力扣每日一题:2646. 最小化旅行的价格总和(2023-12-06)

力扣每日一题 题目&#xff1a;2646. 最小化旅行的价格总和 日期&#xff1a;2023-12-06 用时&#xff1a;30 m 14 s 时间&#xff1a;8ms 内存&#xff1a;42.98MB 思路&#xff1a;先统计旅行中每个节点路过的次数&#xff08;dfs方法&#xff09;&#xff0c;再计算减半后的…