Chiriri's blog Chiriri's blog
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)

Iekr

苦逼后端开发
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)
  • 数据结构

    • 位运算
    • 最基本的数据结构
    • 前缀和数组
    • random的随机行为
    • 对数器
    • 二分法查找
    • 方法参数传递是值还是引用
    • 链表
    • 位图
    • 位运算实现四则运算
      • 加法
      • 减法
      • 乘法
      • 除法
      • 29. 两数相除
    • 二叉树
    • 排序
    • 时间复杂度
    • 队列和栈
    • 递归
    • 堆(优先级队列)
    • 贪心
    • 并查集
    • 图
    • 从暴力递归到动态规划
    • 滑动窗口
    • 单调栈
    • 线段树
  • 数据结构与算法

  • 计算机组成原理

  • 操作系统

  • 408
  • 数据结构
Iekr
2022-02-02
目录

位运算实现四则运算

# 位运算实现四则运算

# 加法

异或运算 是一个无进位加法

int a = 46; //0101110
int b = 20; //0010100
System.out.println(a^b); //58 ==> 0111010
System.out.println(a&b); //4 ==> 0000100  进位位置
System.out.println((a&b) << 1);//8 ==>0001000   需要左移一位才是进位后的结果
//不断的无进位加法 + 进位信息 直到进行信息为空则为 加法
1
2
3
4
5
6

完整写法

	public static int add(int a,int b) {
		int sum = a;
		while (b != 0) { //直接进位信息为空
			sum = a ^ b; //无进位相加
			b = (a&b)<<1; // 进位信息
			a = sum; //a变成无进位信息 加法的结果
		}
		return sum;
	}
1
2
3
4
5
6
7
8
9

# 减法

a - b = a + (-b) = a + (~b + 1)

//减法
	public static int sub(int a,int b) {
		b = add(~b,1);
		return add(a,b);
	}
1
2
3
4
5

# 乘法

这里写图片描述

如果乘数当前位为 1,则取被乘数左移一位的结果加到最终结果中;如果当前位为 0,则取 0 加到乘积中

	//乘法
	public static int multiply(int a, int b) {
		int sum = 0;
		while (b != 0) {
			if ((b & 1) != 0) { //如果b 与 1 不等于0则需要相加
				sum = add(sum, a);
			}
			a = a << 1; //a左移一位0补全
			b = b >>> 1; //b右移一位
		}
		return sum;
	}
1
2
3
4
5
6
7
8
9
10
11
12

# 除法

	public static int div(int a, int b) {
		int x = a < 0 ? add(~a, 1) : a; // 判断是否为负数 如是则转为绝对值计算
		int y = b < 0 ? add(~b, 1) : b;
		int res = 0;
		for (int i = 30; i >= 0; i = add(i, -1)) { // i-- ==> add(i,-1)
			if ((x >> i) >= y) { // 如果x右移i位 >= 被除数 则进入分支
				res |= (1 << i); // 将倍数(位数)结果增加到ans中
				x = add(x, add(~y, 1) << i); // 减掉n倍的被除数
				
			}
		}
		return (a < 0 == b < 0) ? res : add(~res, 1); // 判断ab两数符号是否相等 不相等则返回相反数
	}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 29. 两数相除 (opens new window)

	// 加法
	public static int add(int a, int b) {
		int sum = a;
		while (b != 0) { // 直接进位信息为空
			sum = a ^ b; // 无进位相加
			b = (a & b) << 1; // 进位信息
			a = sum; // a变成无进位信息 加法的结果
		}
		return sum;
	}

	// 减法
	public static int sub(int a, int b) {
		b = add(~b, 1); // 取反+1
		return add(a, b);
	}

	// 乘法
	public static int multiply(int a, int b) {
		int sum = 0;
		while (b != 0) {
			if ((b & 1) != 0) {
				sum = add(sum, a);
			}
			a = a << 1;
			b = b >>> 1;
		}
		return sum;
	}

	// 除法
	public static int div(int a, int b) {
		int x = a < 0 ? add(~a, 1) : a; // 判断是否为负数 如是则转为绝对值计算
		int y = b < 0 ? add(~b, 1) : b;
		int res = 0;
		for (int i = 30; i >= 0; i = add(i, -1)) { // i-- ==> add(i,-1)
			if ((x >> i) >= y) { // 如果x右移i位 >= 被除数 则进入分支
				res |= (1 << i); // 将倍数(位数)结果增加到ans中
				x = add(x, add(~y, 1) << i); // 减掉n倍的被除数
				
			}
		}
		return (a < 0 == b < 0) ? res : add(~res, 1); // 判断ab两数符号是否相等 不相等则返回相反数
	}

	public static int divide(int a, int b) {
		if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE) { // a和b都为最小值 返回1
			return 1;
		} else if (b == Integer.MIN_VALUE) { // 被除数为最小值 返回0
			return 0;
		} else if (a == Integer.MIN_VALUE) { // 除数为最小值
			if (b == add(~1, 1)) { // 被除数为-1 返回最大值
				return Integer.MAX_VALUE;
			} else {
				int c = div(add(a, 1), b); // (a+1)/b = c
				int e = multiply(b, c); // b*c = e
				int f = add(a, add(~e, 1)); // a-(b*c) = f
				int q = div(f, b); // f/b = q
				return add(c, q); // c+q
			}
		} else {
			return div(a, b);
		}
	}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
编辑 (opens new window)
上次更新: 2023/12/06, 01:31:48
位图
二叉树

← 位图 二叉树→

最近更新
01
k8s
06-06
02
进程与线程
03-04
03
计算机操作系统概述
02-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Iekr | Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式