"Coding Interview Guide" -- 只用位运算不用算术运算实现整数的加减乘除运算

题目

  给定两个32位整数a和b,可正、可负、可0,不能使用算术运算符,分别实现a和b的加减乘除运算

要求

  如果给定的a和b执行加减乘除的某些结果本来就会导致数据的溢出,那么你实现的函数不必对那些结果负责

加法运算:a + b = (a ^ b) + ((a & b) << 1)

 1 public int add(int a, int b)
 2 {
 3   int sum = a;
 4   while(b != 0)
 5   {
 6        sum = a ^ b;          // 不带进位的加法
 7        b = (a & b) << 1;     // 进位值
 8        a = sum;
 9   }
10
11   return sum;
12 }

减法运算:a - b = a + (-b)

1 public int sub(int a, int b)
2 {
3     return add(a, negNum(b));
4 }
5
6 public int negNum(int num)
7 {
8     return add(~num, 1);
9 }

乘法运算:a * b = a*(2^0)*b0 + a*(2^1)*b1 + a*(2^2)*b2 + ... + a*(2^(31))*b31

 1 public int mul(int a, int b)
 2 {
 3     int res = 0;
 4     while(b != 0)
 5     {
 6         if((b & 1) != 0)
 7         {
 8             res = add(res, a);
 9         }
10         a <<= 1;
11         b >>>= 1;
12     }
13     return res;
14 }

除法运算:a / b = res  <==> a = b * res

 1 public int divide(int a, int b)
 2 {
 3     if(b == 0)         // 除数不能为0
 4     {
 5         throw new RuntimeException("divisor is 0");
 6     }
 7     if(a == Integer.MIN_VALUE && b == Integer.MIN_VALUE)   // 当a或b为最小值时需分情况讨论
 8     {
 9         return 1;
10     }
11     else if(b == Integer.MIN_VALUE)
12     {
13         return 0;
14     }
15     else if(a == Integer.MIN_VALUE)
16     {
17         int temp = div(add(a, 1), b);
18         return add(temp, div(sub(a, mul(temp, b)), b));
19     }
20     else
21     {
22         return div(a, b);
23     }
24 }
25
26
27 public int div(int a, int b)
28 {
29     int x = isNeg(a) ? negNum(a) : a;     // 不适用于a或b为最小值的情况
30     int y = isNeg(b) ? negNum(b) : b;     // 不适用于a或b为最小值的情况
31     int res = 0;
32     for(int i = 31; i > -1; i = sub(i, 1))
33     {
34         if((x >> i) >= y)
35         {
36             res |= (1 << i);
37             x = sub(x, y << i);
38         }
39     }
40     return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
41 }
42
43
44 public boolean isNeg(int n)
45 {
46     return n < 0;
47 }
  

来源:左程云老师《程序员代码面试指南》

原文地址:https://www.cnblogs.com/latup/p/10986247.html

时间: 2024-11-02 01:31:15

"Coding Interview Guide" -- 只用位运算不用算术运算实现整数的加减乘除运算的相关文章

&quot;Coding Interview Guide&quot; -- 设计一个有getMin功能的栈

[题目] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作 [要求] 1. pop.push.getMin操作的时间复杂度都是O(1) 2. 设计的栈类型可以使用现成的栈结构 [分析] 栈是一种只能在另一端进行操作的具有“先进后出”特性的数据结构,它有push(元素入栈).pop(元素出栈).peek(访问栈顶元素).size(获取栈元素个数)和isEmpty(判断栈是否为空)等基本功能 一般来说,栈并没有提供返回当前栈中最小元素的方法.因为栈只允许在栈顶对元素进行操作

&quot;Coding Interview Guide&quot; -- 判断二叉树是否为平衡二叉树

[题目] 平衡二叉树的性质为:要么是一棵空树,要么任何一个节点的左右子树高度差的绝对值不超过1.给定一棵二叉树的头节点head,判断这棵二叉树是否为平衡二叉树 [要求] 如果二叉树的节点数为N,要求时间复杂度为O(N) [分析] 平衡二叉树要么是一棵空树,要么任何一个节点的左右子树高度差的绝对值不超过1.平衡二叉树的任一子树也是平衡二叉树,所以如果二叉树的某一节点的左右子树高度差的绝对值超过了1,则该二叉树必定不是平衡二叉树.所以在递归求树高的过程中,计算当前节点的左右子树高度差的绝对值是不是超

&quot;Coding Interview Guide&quot; -- 仅用递归函数和栈操作逆序一个栈

[题目] 一个栈依次压入1.2.3.4.5,那么从栈顶到栈底分别为5.4.3.2.1.将这个栈转置后,从栈顶到栈底为1,2,3,4,5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不能使用其它数据结构 [分析] 栈是一种操作受限的数据结构,只能从某一端进行插入和删除和访问元素.能进行插入删除和访问等操作的一端称为“栈顶”,相对的另一端,不能进行任何栈操作,称为栈底.栈中除了栈顶元素外,其它的栈元素都是不允许访问的.所以想要访问栈中其它元素,则只能将将栈中元素依次弹出直到该元素成为栈顶元素

&quot;Coding Interview Guide&quot; -- 在数组中找到一个局部最小的位置

[题目] 定义局部最小的概念:arr长度为1时,arr[0]是局部最小:arr的长度为N(N > 1)时,如果arr[0] < arr[1],那么arr[0]是局部最小,如果arr[N - 1] < arr[N - 2],那么arr[N - 1]是局部最小:如果0<i<N-1,既有arr[i] < arr[i-1], 又有arr[i] < arr[i+1],那么arr[i]是局部最小 给定无序数组arr,已知arr中任意两个相邻的数都不相等.写一个函数,只需返回a

Python 整数和浮点数运算

和数学运算不同的地方是,Python的整数运算结果仍然是整数,浮点数运算结果仍然是浮点数:1 + 2 # ==> 整数 31.0 + 2.0 # ==> 浮点数 3.0 整数和浮点数混合运算的结果就变成浮点数了:1 + 2.0 # ==> 浮点数 3.0 为什么要区分整数运算和浮点数运算呢?这是因为整数运算的结果永远是精确的,而浮点数运算的结果不一定精确,因为计算机内存再大,也无法精确表示出无限循环小数,比如 0.1 换成二进制表示就是无限循环小数.

利用JavaScript实现加减乘除运算

一.问题:利用JavaScript写一个加减乘除运算,输入两个数,判断下拉列框的运算符号,进行相应的运算 二.首先,我利用JavaScript实现简单加法运算,代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="

《Cracking the Coding Interview》——第17章:普通题——题目4

2014-04-28 22:32 题目:不用if语句或者比较运算符的情况下,实现max函数,返回两个数中更大的一个. 解法:每当碰见这种无聊的"不用XXX,给我XXX"型的题目,我都默认处理的是int类型.最高位是符号位,用x - y的符号位来判断谁大谁小.请看下面代码,条件表达式配合异或运算能满足题目的要求. 代码: 1 // 17.4 Find the maximum of two numbers without using comparison operator or if-el

《Cracking the Coding Interview》——第18章:难题——题目1

2014-04-29 00:56 题目:不用算数运算,完成加法. 解法:那就位运算吧,用加法器的做法就可以了. 代码: 1 // 18.1 add two numbers wihout using arithmetic operator. 2 #include <iostream> 3 using namespace std; 4 5 int add(int x, int y) 6 { 7 int sum; 8 int carry; 9 int bx, by; 10 int base; 11

Cracking the Coding Interview 8.7

Given a infinite number of quarters(25cents), dimens(10cents), nickels(5cents) and pennies(1cent), write code to calculate the number of ways of representing n cents. 思路: buf[] = {1,5,10,25} 为了组成n,用到几个25呢?最多n/25个. 如果用1个25,那么问题就变成了用{1,5,10}组成n-25 如果用2