前言
计算机运算以二进制为基础,而二进制的基本运算不是加减乘除,而是与或非异或、位运算。当然这些运算灵活组合运用同样实现数字本有的加减乘除规范。
一、案例
1、加法
设计一个函数把两个数字相加。不得使用 + 或者其他算术运算符。
示例:
输入: a = 1, b = 1
输出: 2
2、除法
给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 ‘*’、除号 ‘/’ 以及求余符号 ‘%’ 。
二、题解
class Solution {
public int add(int a, int b) {
//用与运算和右移得到进位数,通过异或运算得到没有进位的数,然后两者相加
int temp;
while(a != 0){
temp = (a & b) << 1;
b = a ^ b;
a = temp;
}
return b;
}
}
package com.xhu.offer.tencent;
//整数除法
public class Divide {
//其中有一个规律 n << count = (1 << count) * n;说白了右移就是扩大了2的倍数倍。那么除n的就应该1 << count位
public int divide(int a, int b) {
int res = 0;
//溢出情况
if (a == Integer.MIN_VALUE && b == -1) return Integer.MAX_VALUE;
//结果为0的情况
if (a == 0) return 0;
if (a == b) return 1;
//得到结果是否为正
boolean mark = a < 0 && b < 0 || a > 0 && b > 0;
//由于负数转整数可能溢出,所以统一负数处理
if (a > 0) a = -a;
if (b > 0) b = -b;
int count = 0;
while (a < b << count) {
//判断是否存在溢出情况,若有,上一轮的判断条件不算,count++不算
if (count != 0 && b << count - 1 < b << count) {
count--;
break;
}
count++;
}
if (b << count + 1 == a) return (1 << count + 1);
while (count >= 0) {
if (a <= b << count) {
res -= 1 << count;
a -= b << count;
}
count--;
}
return mark ? -res : res;
}
public static void main(String[] args) {
System.out.println(-3 << 29);
System.out.println(-2147483648 * -1);
System.out.println(Integer.MAX_VALUE + 1);
}
}
总结
1)掌握与或非异或及位运算怎么算,以及它们各自的特点是什么,它们之间组合能实现所有数字规范。
参考文献
[1]LeetCode 加法
[1]LeetCode 除法