位运算实现加减乘除(Go语言实现)

位运算实现加减乘除


```go
package main

import (
	. "fmt"
)

//位运算加法的步骤
/*
1。a'=a,b无进位相加就是01得1 11得0 00得0的^异或运算
2.b'=再让a&b得出哪位进位了再让其<<1左移动一位
3.如果b'等于零就是表示无进位信息那a就是最终答案
4.如果有进位信息那a‘,b’作为ab再来一轮
*/
func add(a, b int) int {
	sum := a
	for b != 0 {

		sum = a ^ b //无进位相加
		b = (a & b) << 1
		a = sum

	}

	return sum
}

func negNum(n int) int {
	return add(^n, 1)
	//转负数的经典方式按位取反再加1(因为不能直接用+所以用add代替+1)
}

func minus(a, b int) int {
	//a-b可以转换成将b弄成负的再相加就是减法了

	return add(a, negNum(b))
}
func IsNega(a int) bool {
	return a < 0

}
func multi(a, b int) int {
	flag := 0
	if b < 0 {
		//当b为负数时为了防止其符号位右移导致死循环这边得转成正数参与运算顺便记住这个负号到时候要补回去
		b = ^b + 1
		flag = 1
	}
	//a*b
	result := 0
	for b != 0 { //当b为零时代表所有位上都没1就可以结束循环了
		if b&1 == 1 {
			//如果b&1有结果就说明b第一位有1需要加上这次a的结果
			result = add(result, a)
		}
		//每次a左移,b右移
		a <<= 1
		b >>= 1
	}
	if flag == 1 { //当b为负数时返回补上符号
		return negNum(result)
	}

	return result

}

func div(a, b int) int {
	a1 := a
	b1 := b
	res := 0
	if a < 0 { //进行位运算触发首先要保证两个数为正数
		a1 = negNum(a)
	}
	if b < 0 {
		b1 = negNum(b)
	}
	//a/b=c
	for i := 63; i >= 0; i = minus(i, 1) {
		if (a1 >> i) >= b1 { //如果a右移后大于等于b1就说明最终的c在这位上有1
			res = add(res, 1<<i)  //res就加上这1<<i的数字代表c这位上有1
			a1 = minus(a1, b1<<i) //a1再减去b1往左移对应的内容
			//这样可以判断缩短a1之后缩短右移的位数后是否大于b1
			//然后慢慢缩短右移的位数
			//不减的话就会一直大于,之后每位都是1
		}
	}
	if IsNega(a) == IsNega(b) { //最后就是判断两个是否位负数
		return res //同时为正 或者同时为负
	} else { //直接返回正数
		return negNum(res) //反之加上负号
	}

}
func Newdiv(a, b int) int {
	if a == MinInt && b == MinInt { //两个都为系统最小值的话直接返回1
		return 1
	} else if b == MinInt { //如果b是最小数,b的绝对值是最大的所以结果不用想肯定等于0
		return 0
	} else if a == MinInt {
		if b == negNum(1) { //当a是系统最小值除以-1时等于系统最大值
			//这是约定俗成的规矩
			return MaxInt
		} else {
			//因为系统最小值的绝对值比系统最大值要大
			//所以不能直接放入div里面进行除
			//所以要除以一个数的话先让其加1再去相除
			//得出的结果再去*b看看和a差多少如果差值比b大要结果要+1
			//反之不加
			c := div(add(a, 1), b)
			e := minus(a, multi(c, b))
			return add(c, div(e, b))
		}
	} else {
		return div(a, b)
	}

}

func main() {
	Println(add(46, 20))
	Println(negNum(10))
	Println(multi(10, -10))
	Println(multi(-10, 10))
	Println(div(127, 6))
	Println(MaxInt)
	Println(MinInt)
	Println(Newdiv(MinInt, 5))
	Println(MinInt / 5)
}

``

工具类

type Myi interface {
	int64 | int | uint
}

func Print32[T Myi](num T) {

	for i := 63; i >= 0; i-- {

		if (num & (1 << i)) == 0 {
			print("0")
		} else {
			print("1")
		}
	}
	println()
}

const MaxUint = ^uint(0)

// 当前系统支持的最小uint数值为0,不言而喻
const MinUint = 0

// 产生当前系统支持的最大int数值
// 将当前系统支持的最大uint数值左移一位即可
const MaxInt = int(MaxUint >> 1)

// 产生当前系统支持的最小int数值
// 将当前系统支持的最大int数值的相反数减去1即可
const MinInt = -MaxInt - 1

请添加图片描述

请添加图片描述

请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值