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)

\[2 = \frac{2+1}{2} \times \frac{2^2+1}{2^2} \times \frac{2^4+1}{2^4}\times\frac{2^8+1}{2^8}...
\]

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:

\[\frac{1}{6} = \frac{1}{8} \times \frac{2^2+1}{2^2} \times \frac{2^4+1}{2^4}\times\frac{2^8+1}{2^8}...
\]

Thus we can calculate this(Formula 2)

\[p = \frac{x}{8} \times \frac{2^2+1}{2^2} \times \frac{2^4+1}{2^4}\times\frac{2^8+1}{2^8} \times \frac{2^{16}+1}{2^{16}}
\]

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)

\[\frac{x}{6} = p + \frac{x}{6} - p = p + \frac{1}{6}(x-6p)
\]

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

\[\lfloor \frac{1}{6} (x-6p)\rfloor = \lfloor X \cdot (x-6p) \rfloor
\]

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的更多相关文章

  1. java.lang.IncompatibleClassChangeError: Implementing class的解决办法,折腾了一天总算解决了

    一,问题产生背景 git更新代码重启服务器后,问题就莫名奇妙的产生了,一看报错信息,基本看不懂,然后上百度去查,基本都是说jar包冲突,于是把矛头指向maven 二,问题的解决过程 既然确定了是mav ...

  2. Implementing Navigation with UINavigationController

    Implementing Navigation with UINavigationController Problem You would like to allow your users to mo ...

  3. 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 ...

  4. ios警告:Category is implementing a method which will also be implemented by its primary class 引发的相关处理

    今天在处理项目中相关警告的时候发现了很多问题,包括各种第三方库中的警告,以及各种乱七八糟的问题  先说说标题中的问题  Category is implementing a method which ...

  5. 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参数被 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. Implementing HTTPS Everywhere in ASP.Net MVC application.

    Implementing HTTPS Everywhere in ASP.Net MVC application. HTTPS everywhere is a common theme of the ...

随机推荐

  1. EL表达式格式化日期

    在EL表达式中要显示"yyyy-MM-dd"格式的日期: 使用<fmt:>格式化标签     1 在页面上导入   <%@ taglib prefix=" ...

  2. bzoj 2453: 维护队列

    2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1079  Solved: 503[Submit][Status][Discuss ...

  3. 数学:FFT

    在信息学竞赛中FFT只有一个用处那就是加速多项式的乘法 多项式乘法原本的时间复杂度是O(n^2)的,然后经过FFT之后可以优化为O(nlogn) FFT就是将系数表示法转化成点值表示法相乘,再由点值表 ...

  4. ZOJ 3780 E - Paint the Grid Again 拓扑排序

    https://vjudge.net/problem/49919/origin 题意:给你n*n只出现O和X的字符阵.有两种操作,一种操作Ri将i行全变成X,一种操作Ci将i列全变成O,每个不同的操作 ...

  5. (32位)本体学习程序(ontoEnrich)系统配置说明文档

    1.系统环境 32位 Ubuntu 源代码中已经包含在32位下编译生成的.o文件,配置好依赖库(步骤2)后,参考步骤3则可重新link. link无误即可运行程序. 2.依赖库  2.1 boost_ ...

  6. C# 实现java中 wiat/notify机制

    最近在学习java,看到wiat/notify机制实现线程通信,由于平时工作用的C#,赶紧用C#方式实现一个demo. Java 代码: import java.util.ArrayList; imp ...

  7. uefi模式下win10安装双系统ubuntu18.04LTS

    自己折腾了半天,血与泪啊(难得一个可爱的周末 wwww我一定要写下来 跟这个博客几乎一模一样了 https://blog.csdn.net/xrinosvip/article/details/8042 ...

  8. 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)

    [题意]给定ai,将1~n从小到大插入到第ai个数字之后,求每次插入后的LIS长度. [算法]树状数组||平衡树 [题解] 这是树状数组的一个用法:O(n log n)寻找前缀和为k的最小位置.(当数 ...

  9. RMQ之ST求区间最大值

    题目链接:https://cn.vjudge.net/problem/HRBUST-1188 每一次按照二进制的方式进行更新,二维数组dp [i] [j],i表示下标,j表示从i 开始的往后移动2的j ...

  10. Lucene7.2.1系列(二)luke使用及索引文档的基本操作

    系列文章: Lucene系列(一)快速入门 Lucene系列(二)luke使用及索引文档的基本操作 Lucene系列(三)查询及高亮 luke入门 简介: github地址:https://githu ...