由位运算到操作符,再到逐步理解群论

Step by Step for Understanding from Bitwise to Operators, then Group Theory

是否曾经会有过很努力,还是看不懂别人代码的苦恼?

有时是算法思路堵塞,有时是作者“故意”用了一些奇形怪状的位运算来炫技!

比如交换两个变量,不借助第三者的异或运算^;判断奇偶数用 &运算;置位用左移<>运算等等。

这些代码常见于嵌入式编程(考虑效率),或编程比丑大赛(Hacker)之中。

为什么一般看不懂呢?

因为通常我们脑中并没有很好理解它的意义,而习惯上加、减、乘、除("+-*/")的意义好像都已印入脑中!

但仔细一想,这些"&,|,^,<>,~,"与“加减乘除”其实都一样,没什么区别的,它们都是操作符(Operator) 啊!

操作符绑定两个数,再安一些规则在其中,就形成了!

听不懂?,那么倒要真的问一下自己,是否真的懂了加减乘除啦?(据说博士毕业之前最好都要搞懂)

下面将举一些具体的位操作运算例子,以辅助大家对各操作符意义的理解。

然后结合加减乘除上升到操作符的抽象!

最后再到群论的入门介绍

希望大家领略了群论的风景之后,再回来看自己曾经学过的各个计算机语言(C,C++,C#,Java,Python,Javascript...虽然很多我都不熟?),会有too simple, too young的感慨?~

位操作介绍

位操作主要有与、或、非和异或,下面将介绍各种位操作的基本用法。

0 & 1 = 0

1 & 0 = 0

0 & 0 = 0

1 & 1 = 1

0 | 1 = 1

1 | 0 = 1

0 | 0 = 0

1 | 1 = 1

!0 = 1

!1 = 0

异或

1 ^ 0 = 1

0 ^ 1 = 1

0 ^ 0 = 0

1 ^ 1 = 0

位操作符两边的数a和b只有两个数0和1,加减乘除两边的操作数a和b可以是所有实数(除法b不能为0),这是它们的最大区别,再无其它!

要把运算映射到人可以理解的意义,第一步要把二进制数映到实数(整数),再结合效果map到人习惯理解的意义!

1.判断一个数的奇偶性(不用%2操作)

n = 3# if n is even, will be true, else falsedef f(n):    return n & 1 == 0

f(n)
False
f(4)
True

2.判断一个数是否为2的整数幂

def f(n):    return n & (n-1) == 0

f(4)
True

3.不用临时变量交换两个数

def swap(a,b):    a ^= b    b ^= a    a ^= b    return a,b

x,y = 3,4swap(x,y)
(4, 3)

4.找到数组中出现奇数次的元素:

一个非空数组,只有一个元素出现奇数次,其余出现偶数次,找出那个元素:

arr = [1,2,1,2,4,3,3]res = 0for i in arr:    res ^= i

res#  任何一个数字异或它自己都等于0。也就是说,如果我们从头到尾依次异或数组中的每一个数字,#  那么最终的结果刚好是那个只出现奇数次的数字,因为那些出现偶数次的数字全部在异或中抵消掉了。
4

5.求两个整数的平均值(结果有小数点时抛弃小数点)

def f(a,b):    return (a+b)>>1

f(5,6)
5

6.取两个数的最大值(某些机器上,效率比a>b ? a:b高)

def f(a, b):    return b & ((a-b) >> 31) | a & (~(a-b) >> 31)

f(8,22)
22

7.取两个数的最小值(某些机器上,效率比a>b ? b:a高)

def f(a,b):    return a & ((a-b) >> 31) | b & (~(a-b) >> 31)

f(3,4)
3

8.判断两个数符号是否相同(0算正号)

def f(x,y):    return (x ^ y) >= 0

f(3,4)
True

9.计算2的n次方

def f(n):    return 2<-1)

f(3)
8

10.从低位到高位,取某数的第m位

def f(n,m):    return (n >> (m-1))&1

f(8,4)
1

11.从低位到高位,将某数的第m位置1

def f(n,m):    return n | (1 <-1))

f(8,2)
10

12.取相反数 (注意~是单目运算符)

def f(n):    return ~n+1

f(-5)
5

13.判断两个数是否相等

def f(x1,x2):    return (x1 ^ x2) == 0

f(3,4)
False

14.对n加1,++

def f(n):    return -~n

f(3)
4

15.对n减1,--

def f(n):    return ~-n

f(4)
3

16.取绝对值

def f(n):    return (n ^ (n >> 31)) - (n >> 31)

f(-9)
9

我们总结一下:

  • 任何数和 0 进行 OR 都为自身:x | 0 = x。

  • 任何数和 -1 进行 OR 都为 -1:x | -1 = -1。

  • 任何数和 0 进行 XOR 都为自身:x ^ 0 = x。

  • 任何数和 -1 进行 XOR 都为 ~x:x ^ -1 = ~x。

  • 任何数和其自身进行 XOR 都为0:x ^ x = 0。

  • 对任何数 x 进行 NOT 操作的结果为 -(x + 1),~x = -(x+1)。

  • <

在位数没溢出的情况下,左移一位,可视为乘2操作,左移n位相当于乘以2的n次方

  • >>(有符号右移)该操作数会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0补充,最左侧符号位用原符号位填充。

在位数没溢出的情况下,右移一位,可视为除2操作,右移n位相当于除以2的n次方

所有符号都只是一个代表某种意义的操作符,而已!它和“加减乘除”是完全一样的!

进而我们是不是可以把这种操作符进一步抽象?把它和集合中的元素绑定在一起就形成了群论!

群(group)的基本定义:

群是一个集合G 加上一个操作符运算"#",它结合任何两个元素a和b而形成另一个元素,记为a#b。

要成为群,这个集合和操作运算(G,#)必须满足叫做群公理(group axioms)的四个要求:

  • (1)封闭性(closure):对于所有G中a,b,运算a#b的结果也在G中。
  • (2)结合性(Associativity):对于所有G中的a,b和c,等式 (a#b)#c=a#(b#c)成立。
  • (3)单位元(Identity element):G中存在一个元素e,对于所有G中的元素a,等式 e#a = a#e = a 成立。
  • (4)逆元(Inverse element):对于每个G中的a,存在G中的一个元素b使得 a#b=b#a=e。

注意:

  • (1)"#"可以是带有任何有意义的操作符,有一些不一定满足交换律,即a#b!=b#a,比如矩阵运算。
  • (2)单位元和逆元是唯一的。
  • (3)然后群还有 阿贝尔群,循环群,半群,幺半群,子群,群同态,群同构,陪集,商群等概念,数学家总结的一些定理精彩致极!
  • (4)你可能会感受到到5次方程的根无解问题原来如此简单
  • (5)你可能会看费马小定理变得如此显然,不就是1+1=2一样自然的吗?

希望各位鉴赏完后,再来看前面的位运算操作炫技,是否是雕虫小技??......


数学之水,更多免费干货、敬请关注详查~~

java加减乘除运算代码_从“位运算”炫技到“操作符”,再到逐步理解“群论”...相关推荐

  1. Java位运算,常见的位运算

    前提 位运算符中 ,操作数只能为整型和字符型数据 运算符号 按位与(&):同1则1 → true&&true 操作数1 0 0 1 1 操作数2 0 1 0 1 按位与 0 0 ...

  2. 7、Java四种进制及位运算介绍

    7.Java四种进制及位运算介绍 四种进制: 二进制:0,1 以0b或0B开头 十进制:0-9 八进制:0-7 以数字0开头 十六进制:0-9 及A(10)-F(15) ,以0x或0X开头,此处A-F ...

  3. Java 位运算系列之通过位运算操作状态

    文章目录 回顾 应用 总结 回顾 首先来回顾一下位运算,什么是位运算呢? 位运算就是直接对整数在内存中的二进制位进行操作. 在 Java 语言中,位运算有如下这些: 左移(<<). 右移( ...

  4. 位运算java_Java中的位运算

    Java中的位运算,说实话,工作了两年的时间里,从来没有用过一次,因为平时都是些的是业务代码,很少接触比较底层的东西,我记得第一次在代码中看到还是在HashMap的Hash算法中看到的,这次重拾Jav ...

  5. java int越界_用位运算判断int类型变量越界

    今天在做一道oj题的时候,遇到了一个情景,需要判断经过操作后的int类型数是否越界.我直接很暴力地比较和int类型的最大最小值来判断是否越界.但还想思考一下用位运算判断是否越界的方法,顺便巩固一下位运 ...

  6. java取余位运算_使用位运算取余

    取余运算符为"%".但在以前,CPU采用如下方法计算余数(注意,该方法只对2的N次方数系有效): X & (2^N - 1) 举个例子: 9 % 4 //因为4是2^2:所 ...

  7. java 枚举 或运算_Objective-C 枚举 中位运算 的使用

    前言 Enum,也就是枚举,从C语言开始就有了,C++.Java.Objective-C.Swift这些语言,当然都有对应的枚举类型,功能可能有多有少,但是最核心的还是一个--规范的定义代码中的状态. ...

  8. java实现次方的运算_Java中对于位运算的优化以及运用与思考

    引言 随着JDK的发展以及JIT的不断优化,我们很多时候都可以写读起来易读但是看上去性能不高的代码了,编译器会帮我们优化代码.之前大学里面学单片机的时候,由于内存以及处理器性能都极其有限(可能很多时候 ...

  9. [Leedcode][JAVA][第67题][二进制求和][位运算][字符串]

    [问题描述][简单] 给你两个二进制字符串,返回它们的和(用二进制表示).输入为 非空 字符串且只包含数字 1 和 0.示例 1:输入: a = "11", b = "1 ...

最新文章

  1. aidl使用_借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉
  2. [翻译]深入理解Tornado——一个异步web服务器
  3. 关闭window端口445
  4. nginx高性能WEB服务器系列之七--nginx反向代理
  5. CentOS搭建FTP服务器
  6. 大数据集群中数据互相导通流程汇总(持续更新中)
  7. dubbo yml配置_Spring boot 的profile功能如何实现多环境配置自动切换
  8. requirejs页面刷新失效js报错问题解决方案
  9. DOS批处理高级教程精选(二)
  10. C#解析JSON数据
  11. python简单圣诞树手工折纸_简单立体手工折纸圣诞树的视频教程
  12. python绘制正方形、利用turlr_《像计算机科学家一样思考Python》学习笔记(四)...
  13. C语言-Ubuntu下GDB与GCC的安装与使用
  14. bookStore项目总结
  15. 使用Axis,在webservice的服务器端如何取到客户端的IP地址
  16. 利用vbs读取XML中的某个指定子叶节点 (转)
  17. 解决PLSQL和输入法或QQ冲突问题
  18. OpenGL学习笔记(3) 纹理
  19. mysql8 距离计算_MySQL创建根据经纬度计算距离的函数
  20. 诺基亚linux系统手机系统下载,智能手机操作平台大翻盘 诺基亚拥抱Linux

热门文章

  1. 香港大学工程学院计算机教授,香港大学郑振刚教授访问软件园校区
  2. python使用numpy的np.power函数计算numpy数组中每个数值的指定幂次(例如平方、立方)、np.power函数默认返回整数格式、np.float_power函数默认返回浮点数
  3. R语言导入、读取网络CSV数据(Read a CSV from a URL)实战:R原生read_csv、readr包、data.table
  4. 极端值目标值(exterem or outlier target)对应的核心特征的分布差异分析+结合catboost特种重要度(top10)
  5. 第二章 序列比对——Needleman-Wunsch全局比对
  6. 生物信息学 几个程序
  7. java setdate_java---Set,Date
  8. DeepDive-信息抽取工具安装教程
  9. Java枚举意义在哪_java – 多个if-else或枚举 – 哪一个更好,为什么?
  10. python 同时遍历两个列表并组成一个字典