Implementing x / 6 Using Only Bit Manipulations
This is an interesting question from one of the lab assignments in Introduction to Computer Systems, fall 2018 at Peking University.
Problem Description
Given a 32-bit integer \(x\)(in two's complement), implement a C function that returns \(\frac{x}{6}\) using ONLY bit manipulations(operators like ~ ! | ^ & << >> +). Your function should behave exactly as the C expression x/6.
Hint: You can use the following formula(Formula 1)
\]
Inspiration
Since division is very slow using hardware, compilers often use optimizations to speed up division. For example, gcc will replace x/6 with x*171/1024 when x is relatively small, and implement x*171/1024 with shift left and shift right instructions. However, our function must cover all 32-bit two's complement integers, which means some other techniques are needed to make such replacement possible.
Resolution
We can change Formula 1 into the following form:
\]
Thus we can calculate this(Formula 2)
\]
Which can be implmented using a combination of shift-right and add operations(note that you must program carefully to avoid overflows). However, errors occur since expressions like x>>y return \(\lfloor x/2^y \rfloor\). We can counter the error by this(Formula 3)
\]
Since errors introduced by shift-rights will only cause \(p\) to be smaller than \(\frac{x}{6}\), we can deduce that \(x-6p > 0\). You can then approximate an upper bound of \(x-6p\), which depends on your implementation of Formula 2.
Suppose that \(x-6p < M\)(where M is small), then we can approximate \(\frac{1}{6}\) in Formula 3 using some \(X \approx \frac{1}{6}\) while keeping the equation true
\]
Choose a proper \(X = a/2^b\), and we are done!
/*
* divSix - calculate x / 6 without using /
* Example: divSix(6) = 1,
* divSix(2147483647) = 357913941,
* Legal ops: ~ ! | ^ & << >> +
* Max ops: 40
* Rating: 4
*/
int divSix(int x) {
int p;
int q,y,t;
x=x+(x>>31&5);
p=x>>3;
p=p+(p>>2);
p=p+(p>>4);
p=p+(p>>8);
p=p+(p>>16);
q=~p+1;
t=x+(q<<1)+(q<<2);
t=t+(t<<1)+(t<<3);
return p+(t>>6);
}
Implementing x / 6 Using Only Bit Manipulations的更多相关文章
- java.lang.IncompatibleClassChangeError: Implementing class的解决办法,折腾了一天总算解决了
一,问题产生背景 git更新代码重启服务器后,问题就莫名奇妙的产生了,一看报错信息,基本看不懂,然后上百度去查,基本都是说jar包冲突,于是把矛头指向maven 二,问题的解决过程 既然确定了是mav ...
- Implementing Navigation with UINavigationController
Implementing Navigation with UINavigationController Problem You would like to allow your users to mo ...
- Implementing SQL Server Row and Cell Level Security
Problem I have SQL Server databases with top secret, secret and unclassified data. How can we estab ...
- ios警告:Category is implementing a method which will also be implemented by its primary class 引发的相关处理
今天在处理项目中相关警告的时候发现了很多问题,包括各种第三方库中的警告,以及各种乱七八糟的问题 先说说标题中的问题 Category is implementing a method which ...
- Hadoop on Mac with IntelliJ IDEA - 3 解决MRUnit - No applicable class implementing Serialization问题
本文讲述在IntelliJ IDEA中使用MRUnit 1.0.0测试Mapper派生类时因MapDriver.withInput(final K1 key, final V1 val)的key参数被 ...
- Implementing the skip list data structure in java --reference
reference:http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html The link ...
- The JSR-133 Cookbook for Compiler Writers(an unofficial guide to implementing the new JMM)
The JSR-133 Cookbook for Compiler Writers by Doug Lea, with help from members of the JMM mailing lis ...
- RH253读书笔记(6)-Lab 6 Implementing Web(HTTP) Services
Lab 6 Implementing Web(HTTP) Services Goal: To implement a Web(HTTP) server with a virtual host and ...
- Implementing HTTPS Everywhere in ASP.Net MVC application.
Implementing HTTPS Everywhere in ASP.Net MVC application. HTTPS everywhere is a common theme of the ...
随机推荐
- EL表达式格式化日期
在EL表达式中要显示"yyyy-MM-dd"格式的日期: 使用<fmt:>格式化标签 1 在页面上导入 <%@ taglib prefix=" ...
- bzoj 2453: 维护队列
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1079 Solved: 503[Submit][Status][Discuss ...
- 数学:FFT
在信息学竞赛中FFT只有一个用处那就是加速多项式的乘法 多项式乘法原本的时间复杂度是O(n^2)的,然后经过FFT之后可以优化为O(nlogn) FFT就是将系数表示法转化成点值表示法相乘,再由点值表 ...
- ZOJ 3780 E - Paint the Grid Again 拓扑排序
https://vjudge.net/problem/49919/origin 题意:给你n*n只出现O和X的字符阵.有两种操作,一种操作Ri将i行全变成X,一种操作Ci将i列全变成O,每个不同的操作 ...
- (32位)本体学习程序(ontoEnrich)系统配置说明文档
1.系统环境 32位 Ubuntu 源代码中已经包含在32位下编译生成的.o文件,配置好依赖库(步骤2)后,参考步骤3则可重新link. link无误即可运行程序. 2.依赖库 2.1 boost_ ...
- C# 实现java中 wiat/notify机制
最近在学习java,看到wiat/notify机制实现线程通信,由于平时工作用的C#,赶紧用C#方式实现一个demo. Java 代码: import java.util.ArrayList; imp ...
- uefi模式下win10安装双系统ubuntu18.04LTS
自己折腾了半天,血与泪啊(难得一个可爱的周末 wwww我一定要写下来 跟这个博客几乎一模一样了 https://blog.csdn.net/xrinosvip/article/details/8042 ...
- 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)
[题意]给定ai,将1~n从小到大插入到第ai个数字之后,求每次插入后的LIS长度. [算法]树状数组||平衡树 [题解] 这是树状数组的一个用法:O(n log n)寻找前缀和为k的最小位置.(当数 ...
- RMQ之ST求区间最大值
题目链接:https://cn.vjudge.net/problem/HRBUST-1188 每一次按照二进制的方式进行更新,二维数组dp [i] [j],i表示下标,j表示从i 开始的往后移动2的j ...
- Lucene7.2.1系列(二)luke使用及索引文档的基本操作
系列文章: Lucene系列(一)快速入门 Lucene系列(二)luke使用及索引文档的基本操作 Lucene系列(三)查询及高亮 luke入门 简介: github地址:https://githu ...