第1题:

/*
* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) {
return (~(x&y))&(~((~x)&(~y)));
}

第2题:

二进制补码表示的最小值为0x80000000

/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 1<<31;
}

第3题:

二进制补码表示的最大值为0x7FFFFFFF

tmax+1的相反数是本身,!!x_1是为了消除x=-1的影响

//2
/*
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
int x_1=x+1;
return (!(((~x_1)+1)^x_1))&(!!x_1);
}

第4题:

0xAAAAAAAA正好对应所有奇数位是1的情况

因为题目限制常数只能使用0到255,所以不能直接使用0xAAAAAAAA

通过(0xAA<<8)+0xAA创造0x0000AAAA

通过(half_bits<<16)+half_bits创造0xAAAAAAAA

先用(x&all_bits)清除偶数位

/*
* allOddBits - return 1 if all odd-numbered bits in word set to 1
* where bits are numbered from 0 (least significant) to 31 (most significant)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
int half_bits = (0xAA<<8)+0xAA;
int all_bits = (half_bits<<16)+half_bits;
return !((x&all_bits)^all_bits);
}

第5题:

/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return (~x)+1;
}

第6题:

x-0x30,如果结果的符号位为1,说明x-0x30<0

0x39-x,如果结果的符号位为1,说明0x39-x<0

目标是得到,当x-0x30<0为0,0x39-x<0也为0时,最终结果才为1

001101011000

/*
* isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
* Example: isAsciiDigit(0x35) = 1.
* isAsciiDigit(0x3a) = 0.
* isAsciiDigit(0x05) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 3
*/
int isAsciiDigit(int x) {
int left_bool = ((x+(~0x30)+1)>>31)&1;
int right_bool = ((0x39+(~x)+1)>>31)&1;
return !((left_bool^right_bool)|(left_bool&right_bool));
}

第7题:

~0为0xFFFFFFFF

当x!=0时,!x=0, (!(x)+(~0)=0xFFFFFFFF, (j&y)=y, (~j)&z=0

当x==0时,!x=1, (!(x)+(~0)=0, (j&y)=0, (~j)&z=z

/*
* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z) {
int j = !(x)+(~0);
return (j&y)|((~j)&z)
}

第8题:

一开始的想法:未考虑x,y异号,在x、y最大和最小时,相减会溢出

改正后的想法:考虑两种情况,

异号时直接看x的符号,x为正数则x>y,否则x<y

同号时相减,看结果的符号

/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y) {
int x_sign = (x>>31)&1;
int y_sign = (y>>31)&1;
int same_or_dif = (x_sign^y_sign);
return (same_or_dif&x_sign)|(!same_or_dif&!((y+(~x)+1)>>31)&1);
}

第9题:

0和0x80000000的相反数是其本身

利用了0+1=1,0xFFFFFFFF+1=0的规律

如果x==0,则x和x的相反数的符号移位|的结果仍为0

如果x!=0,则x和y的相反数的符号移位|的结果为0xFFFFFFFF

/*
* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) {
return ((x>>31)|(((~x)+1)>>31))+1;
}

第10题:

原文链接:https://blog.csdn.net/m0_51335239/article/details/125849757

我想得到第一行的异或统一正负数和之后的分而治之思想,但是不会具体落实,水平还是不够

/* 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;//0或16
temp = temp >> bit_16;
bit_8 = !!(temp >> 8) << 3;//0或8
temp = temp >> bit_8;
bit_4 = !!(temp >> 4) << 2;//0或4
temp = temp >> bit_4;
bit_2 = !!(temp >> 2) << 1;//0或2
temp = temp >> bit_2;
bit_1 = !!(temp >> 1);//0或1
return 1 + bit_1 + bit_2 + bit_4 + bit_8 + bit_16;
}

第11题:

首先判断是不是+0.0和-0.0

new_f是uf的绝对值,我也不知道为什么题目说是unsigned int,测试数据会出现负数0x80000000

然后判断是不是NaN

最后分别处理非规格化和规格化,非规格化数左移一位,规格化数的阶码部分加1

s是uf的符号,|s为了还原uf的符号

//float
/*
* floatScale2 - 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 floatScale2(unsigned uf) {
int new_f = uf & (~(1<<31));
if (!new_f)
{
if(uf>>31)
{
return uf;
}
return 0;
}
else
{
int exp = new_f>>23;
int s = uf&(1<<31);
if(!(exp^0xFF)&&(new_f<<8))
{
return uf;
}
else if(!exp)
{
return (new_f<<1)|s;
}else
{
return (new_f+(1<<23))|s;
}
}
}

第12题:

https://www.cnblogs.com/zhiyiYo/p/16242033.html

/*
* floatFloat2Int - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf) {
// 计算阶码
unsigned exp = (uf & 0x7f800000) >> 23;
int e = exp - 127; // 0或小数直接返回 0
if (e < 0) {
return 0;
} // NaN 或者 无穷大
if (e > 31) {
return 0x80000000;
} // 尾数
int frac = (uf & 0x7fffff) | 0x800000; // 移动小数点
if (e > 23) {
frac <<= (e - 23);
} else {
frac >>= (23 - e);
} // 符号位不变
if (!((uf >> 31) ^ (frac >> 31))) {
return frac;
} // 符号位变化,且当前符号为负,说明溢出
if (frac >> 31) {
return 0x80000000;
} // 符号变化,返回补码
return ~frac + 1;
}

第13题:

参考原书第三版P82页图2-36内容

/*
* floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) {
if(x<-149){
return 0;
}else if (x>127)
{
return 0x7f800000;
}else
{
if(x<-126)
{
return 1<<(23+x+126);//非规格化数
}
return (x+127)<<23;//规格化数
}
}

csapp-datalab(菜鸟小白版)的更多相关文章

  1. 模拟实现 Promise(小白版)

    模拟实现 Promise(小白版) 本篇来讲讲如何模拟实现一个 Promise 的基本功能,网上这类文章已经很多,本篇笔墨会比较多,因为想用自己的理解,用白话文来讲讲 Promise 的基本规范,参考 ...

  2. 2021 小白版,360 行行行转 IT

    hey guys ,我是 cxuan,这一篇文章我就要和你聊聊编程如何学习,这一篇文章涉及的内容简直太多了,我将从入门开始,一步一步到如何提高,然后到一些学习的相关问题,还有一些计算机相关的术语等,干 ...

  3. SVN导出/导入、SVN备份/还原 【小白版】

    一.导出: 1.进入svn安装路径bin文件夹下,使用 cd 命令. 在windows下,win+R 键入 cmd 回车 打开命令窗口cmd,进入下列目录(svn服务器安装目录bin): " ...

  4. TransMac Win系统下制作 OS X启动盘图文教程超详细小白版

    1软件安装好后把准备好的8G或者8G以上U盘插到电脑上:右键以管理员身份运行如                     <ignore_js_op> 2打开软件后右键先格式化U盘操作如下图 ...

  5. css3之3D魔方动画(小白版)

      在这里分享一下3D魔方动画,html5+CSS3即可完成~无图无真相,先上效果图 第一步非常简单,就是先将魔方的结构画出来.大家都玩过魔方,知道魔方是一个有六个面的正方体.这里我们先写一个大的di ...

  6. Ubuntu1.6安装Go【小白版】

    [安装golang,并配置环境变量]1.将go下载到Home目录并解压 一键解压会 自动会解压到 Home/go目录. 2.设置环境变量 nano是一种文本编辑器,也可以用其他的编辑器. 输入以下命令 ...

  7. Ubuntu 16.04安装JDK并配置环境变量-【小白版】

    系统版本:Ubuntu 16.04 JDK版本:jdk1.8.0_121 1.官网下载JDK文件jdk-8u121-linux-x64.tar.gz 我这里下的是最新版,其他版本也可以 2.创建一个目 ...

  8. CSAPP DataLab

    注意不同版本的题目可能会有所不同,搜了很多他们的题目和现在官网给的实验题都不一样,自己独立思考完整做一遍顺便记录一下. PS:这些难度为1的题有的说实话我都做了挺久的,不过完整做一遍感觉很有意思,这些 ...

  9. makefile for Linux纯小白版

    某大佬曾说过: 不会makefile,不要说你会linux,因为makefile是合格程序员的必经之路 首先你要有个vi或者emacs 之类的编辑器 编写几个程序 test1.c #include&l ...

  10. CSAPP 之 DataLab 详解

    前言 本篇博客将会剖析 CSAPP - DataLab 各个习题的解题过程,加深对 int.unsigned.float 这几种数据类型的计算机表示方式的理解. DataLab 中包含下表所示的 12 ...

随机推荐

  1. 优先队列(PriorityQueue)

    > 此代码是在最大堆的基础上二次封装,请先阅读底层代码MaxHeap 优先队列 普通队列:先进先出:后进后出 优先队列:出队顺序和⼊入队顺序无关:和优先级相关: 为什么使用堆 代码清单 Queu ...

  2. #高斯消元,概率期望,动态规划#洛谷 3211 [HNOI2011]XOR和路径

    题目 分析 由于不同二进制位互不影响,所以考虑按位处理 设\(dp[i]\)表示第\(i\)个点某一位为1的概率,那么 \[dp[i]=\frac{1}{deg[i]}(\sum_{(i,u)=0}d ...

  3. [一本通1681]统计方案 题解(Meet in mid与逆元的结合)

    题目描述 小\(B\)写了一个程序,随机生成了\(n\)个正整数,分别是\(a[1]-a[n]\),他取出了其中一些数,并把它们乘起来之后模\(p\),得到了余数\(c\).但是没过多久,小\(B\) ...

  4. C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析

    C# Methods 方法是一段代码,只有在调用时才会运行. 您可以将数据(称为参数)传递给方法. 方法用于执行某些操作,也被称为函数. 为什么使用方法?为了重用代码:定义一次代码,然后多次使用. 创 ...

  5. Numpy线性计算

    Numpy内置方法以及numpy.linalg模块可实现矩阵乘法.矩阵分解.矩阵行列式等线性代数的计算. In [1]: import numpy as np In [2]: x = np.arang ...

  6. unknow or unsupported command install

    错误原因: 今天使用pip下载labelimg时,出现了"unknow or unsupported command install"的错误,这是由于电脑有多个pip文件路径所导致 ...

  7. Qt:获取WIFI列表

    示例:使用QT来获取Windows电脑WIFI列表中所有WIFI的名称,实际是执行CMD命令来完成(netsh wlan show networks) // 获取WIFI列表 QProcess pro ...

  8. C++调用Python-6:调用Python类

    # mytest.py class Test: def hello(self): print("this is test class hello function no params ret ...

  9. Python读写json文件--json

    import json # 将数据写入json文件 def json_write_file(): data={'name':'张三','age':12} with open('json.json',' ...

  10. 重新点亮linux 命令树————目录相关[三]

    前言 简单介绍一些目录命令 正文 主要介绍三个命令 cd 路径切换 cd 这个命令用于切换当前目录的. 切换有三种形式. 以/开头的是绝对路径,比如/home. 以.开头的是相对路径,比如说./ser ...