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

news2024/11/27 20:59:49

还是那句话,稳住心态,稳住心态,稳住心态。心里别慌,心里别慌,心里别慌。

第15题,howManyBits,返回用二进制补码形式表示x所需的最小二进制位数。比如howManyBits(12) = 5,12可以被表示为0 1100B,最高位的0为符号位,这样子一共需要5个二进制位来表示x;再比如howManyBits(298) = 10,298可以被表示为01 0010 1010B,最高位的0为符号位,这样子一共需要10个二进制位来表示x;接着比如howManyBits(-5) = 4,-5可以被表示为0xFFFF FFFB,从左到右删除掉连续的1,但最后仍还剩下一个1,即得到了1011B,最高位的1为符号位,这样子一共需要4个二进制位来表示x(1011B各位取反加一可以得到0101B也就是5);接着howManyBits(0)  = 1,0可以被表示为0B,符号位为0,一共需要1个二进制位;howManyBits(-1) = 1,-1可以被表示为1B,符号位为1,一共需要1个二进制位;在这里0被当作正的0而不是负的0,就好像int型的0是0x0而不是0x8000 0000一样。最后一个例子howManyBits(0x80000000) = 32,0x8000 0000,从左到右删除掉连续的1,但最后仍还剩下一个1,结果还是0x8000 0000,最高位为符号位,这样子一共需要32个二进制位来表示x。那么我们该怎么写出这个函数呢?

为了便于思考,我们首先先分两类讨论。第一类,当x为正数时,我们可以简单的将x*2,也就是将x左移一位,然后统计x<<1中有几位,比如x=5=101B,x<<1=1010B,这时x<<1中有4位,所以用二进制补码表示x需要4位,而事实也正好是这样;第二类,当x为负数时,就不能简单的统计x<<1中的位数了,比如-5=0xFFFF FFFB,(-5)<<1之后的结果还是0xFFFF FFF6,统计其中的位数,发现还是32位,所以不能简单的统计x<<1中的位数。那么我们该如何去掉从左到右删除掉连续的1,只留下一个1呢?发现可以通过异或的方法,x^(x<<1),这样子就去掉了连续的1,只留下一个1啦!而对于正数来说,x^(x<<1)中的比特位数与x<<1一样。所以综上所述,无论x是正数还是负数,都可以只统计x^(x<<1)中的比特位数。在这里引入变量"int temp=x^(x<<1)"。

接着如何高效的统计temp中的比特位数呐?有这么一种思路,先看能不能用16位表示x,如果16位不够,那么记录下来16位不够,然后让temp=temp>>16,接着看8位够不够表示此时的temp,也就是8位够不够表示x^(x<<1)的高8位,如果能够的话,怀疑8位多了,所以记录下来8位足够,然后temp还是等于temp,接着看4位够不够表示此时的temp... ...下面结合例子来讲讲吧: 

假设有一个变量x,其十六进制表示形式为0x0177 7FFF,那么temp为0x0399 8001。先看0x0399 8001可以被用16位非补码表示嘛?(因为temp=x^(x<<1)已经考虑了符号位的问题,所以这里问题只需要简简单单的考虑即可)发现不够,所以记录下来先需要16位,这样子低位的16位已经被记录下来了,把高16位拿到低16位看低16位的情况,也就是看0x0000 0399。0x0000 0399能被8位表示嘛?发现不够,所以记录下来还需要8位,这样子第16到第23位已经被记录下来了,再把8位拿到低位,即得到了0x0000 0003。0x0000 0003能被4位表示嘛?发现绰绰有余,所以记录下来不需要4位,然后不把4位拿到低位,还是0x0000 0003,它能被2位表示嘛?发现刚刚好,但是仍然记录下来不需要2位,然后不把2位拿到低位,还是0x0000 0003,他能被1位表示嘛?发现不够,所以记录下来需要1位。这时还少计算了1位,所以还要加1。

现在结合案例,我们思考该如何编写代码呢?首先如何判断能不能被16、8、4、2、1位表示呢?右移16、8、4、2、1位之后两次逻辑取非即可。那么如何记录下来需要16、8、4、2、1位呢?右移16、8、4、2、1位之后两次逻辑取非的结果,再左移4、3、2、1、0位即可。那么如何判断是否需要把temp的高位移到低位呢?让temp右移“右移16、8、4、2、1位之后两次逻辑取非的结果”即可。如果不能被16、8、4、2、1位表示,那么“右移16、8、4、2、1位之后两次逻辑取非的结果”就会是0;如果能被16、8、4、2、1位表示,那么“右移16、8、4、2、1位之后两次逻辑取非的结果”就会是1。同样也只有不能被16、8、4、2、1位表示的时候,才需要把temp的高位移到低位,此时“右移16、8、4、2、1位之后两次逻辑取非的结果”就会是1,让temp右移“右移16、8、4、2、1位之后两次逻辑取非的结果”,也正好实现了把temp的高位移到低位。代码如 图1:编写第15个函数howManyBits 所示。检查该函数的过程如 图2:检查第15个函数howManyBits 所示。

    int temp = x ^ (x << 1);
    int bit_16,bit_8,bit_4,bit_2,bit_1;
    bit_16 = !!(temp >> 16) << 4;
    temp = temp >> bit_16;
    bit_8 = !!(temp >> 8) << 3;
    temp = temp >> bit_8;
    bit_4 = !!(temp >> 4) << 2;
    temp = temp >> bit_4;
    bit_2 = !!(temp >> 2) << 1;
    temp = temp >> bit_2;
    bit_1 = !!(temp >> 1);
    return 1 + bit_1 + bit_2 + bit_4 + bit_8 + bit_16;

图1:编写第15个函数howManyBits) 

图2:检查第15个函数howManyBits

接着第16个函数,isNonZero,不使用逻辑非运算符!,检查x是否非0,比如isNonZero(3) = 1, isNonZero(0) = 0。怎么办呢?想一想发现,除了0之外,+1和-1位或的结果为0xFFFF FFFF,+2与-2位或的结果也是0xFFFF FFFF,+3与-3位或的结果也是0xFFFF FFFF... ...+2147483627与-2147483647位或的结果还是0xFFFF FFFF,甚至-2147483648与+2147483648(虽然不存在)位或的结果也还是0xFFFF FFFF,而+0与-0位或的结果却是0。利用这个性质,我们可以写出如 图3:编写第16个函数isNonZero 所示的代码。检查第16个函数的过程如 图4:检查第16个函数isNonZero 所示。

  int ret = ~x + 1;  
  ret = ret | x;       
  return (ret >> 31) & 1;

图3:编写第16个函数isNonZero

图4:检查第16个函数isNonZero

第17个函数,isPower2,判断x是不是2的1、2、3、4... ...次幂,如果是的话,返回1,否则返回0。我们该怎么做这道题呢? 注意没有负数是2的多少次幂。顺着这个思路,我们首先排除0和负数,排除0可以用!!x表示,排除负数可以用!(x>>31)表示。这时如何判断x是不是2的1、2、3、4... ...次幂呢?我们关注这些数的性质,0x0000 8000,0x0000 4000,我们发现其仅有除第一位以外的一位为1,其余位全部为0,这些数加上0xFFFF FFFF之后的结果,与这些本身位与的结果一定为0,而其它数加上0xFFFF FFFF之后再与本身位与的结果必不为0。所以我们可以利用这个性质,写出表达式!(x&(x+~0))。最终的代码如 图5:编写第17个函数isPower2 所示,检查过程如 图6:检查第17个函数isPower2 所示。

  int y = x+~0;
  return !(x&y)&!(x>>31)&!!x;

图5:编写第17个函数isPower2

图6:检查第17个函数isPower2) 

/* howManyBits - return the minimum number of bits required to represent x in
 *             two's complement
 *  Examples: howManyBits(12) = 5
 *            howManyBits(298) = 10
 *            howManyBits(-5) = 4
 *            howManyBits(0)  = 1
 *            howManyBits(-1) = 1
 *            howManyBits(0x80000000) = 32
 *  Legal ops: ! ~ & ^ | + << >>
 *  Max ops: 90
 *  Rating: 4
 */
int howManyBits(int x) {
  int temp = x ^ (x << 1);
  int bit_16,bit_8,bit_4,bit_2,bit_1;
  bit_16 = !!(temp >> 16) << 4;
  temp = temp >> bit_16;
  bit_8 = !!(temp >> 8) << 3;
  temp = temp >> bit_8;
  bit_4 = !!(temp >> 4) << 2;
  temp = temp >> bit_4;
  bit_2 = !!(temp >> 2) << 1;
  temp = temp >> bit_2;
  bit_1 = !!(temp >> 1);
  return 1 + bit_1 + bit_2 + bit_4 + bit_8 + bit_16;
}
/* 
 * isNonZero - Check whether x is nonzero using
 *              the legal operators except !
 *   Examples: isNonZero(3) = 1, isNonZero(0) = 0
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 10
 *   Rating: 4 
 */
int isNonZero(int x) {
  int ret = ~x + 1;  
  ret = ret | x;       
  return (ret >> 31) & 1;
}
/*
 * isPower2 - returns 1 if x is a power of 2, and 0 otherwise
 *   Examples: isPower2(5) = 0, isPower2(8) = 1, isPower2(0) = 0
 *   Note that no negative number is a power of 2.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 4
 */
int isPower2(int x) {
  int y = x+(~1)+1;
  return !(x&y) & !(x>>31) & !!x;
}

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

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

相关文章

高级实现Java的七大热门技术框架解析源码特性分析

Java是一门广泛应用的编程语言&#xff0c;拥有众多热门技术框架。本文将通过解析源码和特性分析&#xff0c;带你深入了解Java的七大热门技术框架&#xff0c;并提供相关示例代码。 一、Spring框架 Spring是Java最流行的开发框架之一&#xff0c;提供了依赖注入&#xff08;D…

电商早报 | 12月7日| 阿里巴巴分红179亿,破历史记录

阿里巴巴将派发25亿美元年度股息 12月6日消息&#xff0c;阿里巴巴发布公告&#xff0c;将向截至2023年12月21日香港时间及纽约时间收市时登记在册的普通股持有人和美国存托股持有人&#xff0c;就2023财年首次派发年度股息&#xff0c;金额分别为每股普通股0.125美元或每股美…

mysql知识分享(包含安装卸载)(一)

如果博客有错误&#xff0c;请佬指正。 目录 注意&#xff1a;打开cmd时要有管理员身份打开&#xff0c;重要 为何使用数据库&#xff1f; 数据库的相关概念 关系型数据库 关系型数据库设计规则 表&#xff0c;记录&#xff0c;字段 表的关联关系 一对一关联 一对多关系 …

如何衡量和提高测试覆盖率?

衡量和提高测试覆盖率&#xff0c;对于尽早发现软件缺陷、提高软件质量和用户满意度&#xff0c;都具有重要意义。如果测试覆盖率低&#xff0c;意味着用例未覆盖到产品的所有代码路径和场景&#xff0c;这可能导致未及时发现潜在缺陷&#xff0c;代码中可能存在逻辑错误、边界…

[Geek Challenge 2023] web题解

文章目录 EzHttpunsignn00b_Uploadeasy_phpEzRceezpythonezrfi EzHttp 按照提示POST传参 发现密码错误 F12找到hint&#xff0c;提示./robots.txt 访问一下&#xff0c;得到密码 然后就是http请求的基础知识 抓包修改 最后就是 我们直接添加请求头O2TAKUXX: GiveMeFlag 得到…

vue中的动画组件使用及如何在vue中使用animate.css

“< Transition >” 是一个内置组件&#xff0c;这意味着它在任意别的组件中都可以被使用&#xff0c;无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发&#xff1a; 由 v-if 所触发的切换由 v-show 所触…

用 C 写一个卷积神经网络

用 C 写一个卷积神经网络 深度学习领域最近发展很快&#xff0c;前一段时间读transformer论文《Attention Is All You Need》时&#xff0c;被一些神经网络和深度学习的概念搞得云里雾里&#xff0c;其实也根本没读懂。发现深度学习和传统的软件开发工程领域的差别挺大&#xf…

数据结构:图文详解双向链表的各种操作(头插法,尾插法,任意位置插入,查询节点,删除节点,求链表的长度... ...)

目录 一.双向链表的概念 二.双向链表的数据结构 三.双向链表的实现 节点的插入 头插法 尾插法 任意位置插入 节点的删除 删除链表中第一次出现的目标节点 删除链表中所有与关键字相同的节点 节点的查找 链表的清空 链表的长度 四.模拟实现链表的完整代码 前言&am…

多人群聊代码

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

5G - NR物理层解决方案支持6G非地面网络中的高移动性

文章目录 非地面网络场景链路仿真参数实验仿真结果 非地面网络场景 链路仿真参数 实验仿真结果 Figure 5 && Figure 6&#xff1a;不同信噪比下的BER和吞吐量 变量 SISO 2x2MIMO 2x4MIMO 2x8MIMOReyleigh衰落、Rician衰落、多径TDL-A(NLOS) 、TDL-E(LOS)(a)QPSK (b)16…

echarts环形饼图

效果示例 代码汇总 pieCharts() {let data [];const providerResult [{name: 智诺, value: 23},{name: 海康, value: 5},{name: 大华, value: 5}, {name: 云科, value: 23},{name: 四信, value: 22},{name: 九物, value: 22}]let charts echarts.init(document.getElemen…

700G全球30米高程DEM原始数据

这里&#xff0c;为大家分享700G的全球30米高程原始数据。 全球30米高程覆盖范围 NASA全球30米SRTM高程DEM数据范围在南纬56度到北纬61度范围之间&#xff0c;共分为14520个区域范围。 每个区域范围在经纬度方向的跨度均为1度大小&#xff0c;将该接图表在微图中与影像叠加之…

【C++】如何优雅地把二维数组初始化为0

2023年12月7日&#xff0c;周四上午 目录 为什么要初始化二维数组不优雅的初始化方式&#xff1a;使用两个for循环优雅的初始化方式一&#xff1a;使用初始化列表优雅的初始化方式二&#xff1a;使用memset函数 为什么要初始化二维数组 如果不初始化二维数组&#xff0c;那么…

海云安参与制定《信息安全技术 移动互联网应用程序(App)软件开发工具包(SDK)安全要求》标准正式发布

近日&#xff0c;由TC260&#xff08;全国信息安全标准化技术委员会&#xff09;归口 &#xff0c;主管部门为国家标准化管理委员会&#xff0c;深圳海云安网络安全技术有限公司&#xff08;以下简称“海云安”&#xff09;等多家相关企事业单位共同参与编制的GB/T 43435-2023《…

在Mac上安装Windows应用程序的简便方法:CrossOver for Mac

对于许多Mac用户来说&#xff0c;有时候他们可能需要使用一些只有在Windows上才能找到的应用程序。以前&#xff0c;解决这个问题的方法是通过安装Windows虚拟机或使用双系统来在Mac上运行Windows应用程序。但这些方法需要额外的硬件资源和时间来配置&#xff0c;并且可能会导致…

JVM GUI可视化监控及诊断工具

工具既述 使用命令行工具或组合能帮您获取目标Java应用性能相关的基础信息&#xff0c;但它们存在下列局限&#xff1a; 无法获取方法级别的分析数据&#xff0c;如方法间的调用关系、各方法的调用次数和调用时间等&#xff08;这对定位应用性能瓶颈至关重要&#xff09;。要…

antdesign前端一直加载不出来

antdesign前端一直加载不出来 报错&#xff1a;Module “./querystring” does not exist in container. while loading “./querystring” from webpack/container/reference/mf at mf-va_remoteEntry.js:751:11 解决方案&#xff1a;Error: Module “xxx“ does not exist …

删除Ubuntu系统中的loop

sudo apt autoremove --purge snapd

【Windows Server 2019】 IIS+php56+mysql56470

文章目录 一、安装web服务器&#xff08;IIS&#xff09;二、安装php 5.6.31 nts1、前置配置2、设置iis3、验证php安装 三、安装MySQL下载Navicat Premium 四、测试 一、安装web服务器&#xff08;IIS&#xff09; 前面不多说&#xff0c;在角色服务中选择如下内容&#xff1a…

Python中的深拷贝和浅拷贝的区别

目录 一、深拷贝和浅拷贝的概念 二、Python中的深拷贝和浅拷贝实现 三、深拷贝和浅拷贝的区别及适用场景 四、如何选择深拷贝和浅拷贝 五、总结 在Python中&#xff0c;深拷贝和浅拷贝是非常重要的概念&#xff0c;它们在处理对象和数据结构时有着截然不同的行为。理解深拷…