golang-math实用小技巧
返回a/b向上舍入最接近的整数
func divRoundUp(n, a uintptr) uintptr {return (n + a - 1) / a
}
这个方法用过的人应该不少,最典型的就是分页计算。
判断x是否为2的n次幂
func isPowerOfTwo(x uintptr) bool {return x&(x-1) == 0
}
这个也挺容易理解的,唯一需要注意的是x需要大于0,因为该等式0也是成立的。
向上/下将x舍入为a的倍数,且a必须是2的n次幂
// 向上将x舍入为a的倍数,例如:x=6,a=4则返回值为8
func alignUp(x, a uintptr) uintptr {return (x + a - 1) &^ (a - 1)
}// 向上将x舍入为a的倍数,例如:x=6,a=4则返回值为4
func alignDown(x, a uintptr) uintptr {return x &^ (a - 1)
}
在这里老许再次明确一个概念,2的n次幂即为1左移n位
。然后上述代码中^
为单目运算法按位取反,则^ (a - 1)
的运算结果是除了最低n位为0其余位全为1。剩余的部分则是一个简单的加减运算以及按位与。
上述代码分开来看每一部分都认识,合在一起就一脸懵逼了。幸运的是,经过老许的不懈努力终于找到了一种能够理解的方式。
以x=10,a=4
为例。a
为2的2次幂即1左移2位。x
可看作两部分之和,第一部分x1为0b1000
,第二部分x2为0b0011
。x
的拆分方式是1左移n
位可得到a
来决定的,即x的最低n位为x2,x1则为x-x2。因此x1相当于0b10左移2位得到,即x1已经是a的整数倍,此时x2只要大于0则x2+a-1一定会向前进1,x1+1
或x1
不就是x向上舍入的a的整数倍嘛,最后和^ (a - 1)
进行与运算将最低2位清零得到最终的返回结果。
有一说一,我肯定是写不出这样的逻辑,这也令我不得不感叹大佬们对计算机的理解简直出神入化。这样的函数牛逼归牛逼,但是在实际开发中还是尽量少用。一是有使用场景的限制(a必须为2的n次幂),二是不易理解,当然炫技和装逼除外(性能要求极高也除外)。
布尔转整形
// bool2int returns 0 if x is false or 1 if x is true.
func bool2int(x bool) int {return int(uint8(*(*uint8)(unsafe.Pointer(&x))))
}
如果让我来写这个函数,一个稀松平常的switch
就完事儿,现在我又多了一种装逼的套路。老许在这里特别友情提示,字节切片和字符串也可使用上述方式进行相互转换。
计算不同类型最低位0的位数
var ntz8tab = [256]uint8{0x08, ..., 0x00,
}
// Ctz8 returns the number of trailing zero bits in x; the result is 8 for x == 0.
func Ctz8(x uint8) int {return int(ntz8tab[x])
}const deBruijn32ctz = 0x04653adfvar deBruijnIdx32ctz = [32]byte{0, 1, 2, 6, 3, 11, 7, 16,4, 14, 12, 21, 8, 23, 17, 26,31, 5, 10, 15, 13, 20, 22, 25,30, 9, 19, 24, 29, 18, 28, 27,
}// Ctz32 counts trailing (low-order) zeroes,
// and if all are zero, then 32.
func Ctz32(x uint32) int {x &= -x // isolate low-order bity := x * deBruijn32ctz >> 27 // extract part of deBruijn sequencei := int(deBruijnIdx32ctz[y]) // convert to bit indexz := int((x - 1) >> 26 & 32) // adjustment if zeroreturn i + z
}const deBruijn64ctz = 0x0218a392cd3d5dbfvar deBruijnIdx64ctz = [64]byte{0, 1, 2, 7, 3, 13, 8, 19,4, 25, 14, 28, 9, 34, 20, 40,5, 17, 26, 38, 15, 46, 29, 48,10, 31, 35, 54, 21, 50, 41, 57,63, 6, 12, 18, 24, 27, 33, 39,16, 37, 45, 47, 30, 53, 49, 56,62, 11, 23, 32, 36, 44, 52, 55,61, 22, 43, 51, 60, 42, 59, 58,
}// Ctz64 counts trailing (low-order) zeroes,
// and if all are zero, then 64.
func Ctz64(x uint64) int {x &= -x // isolate low-order bity := x * deBruijn64ctz >> 58 // extract part of deBruijn sequencei := int(deBruijnIdx64ctz[y]) // convert to bit indexz := int((x - 1) >> 57 & 64) // adjustment if zeroreturn i + z
}
Ctz8
、Ctz32
和Ctz64
分别计算无符号8、32、64位数最低位为0的个数,即某个数左移的位数。
函数的作用通过翻译倒是能理解,我也能深刻的明白这是典型的空间换时间,然而要问一句为什么我是万万答不上来的。不过老许已经替你们找好了答案,原因就藏在这篇Using de Bruijn Sequences to Index a 1 in a Computer Word论文中。欢迎巨佬们去挑战一下,而我只想坐享其成,那么在巨佬们分析完这篇论文之前就让这些函数安家在我的收藏栏里方便以后炫技。
这里特别说明,术业有专攻,我们不一定要所有东西都会,但要尽可能知道有这么一个东西存在。这即是老许为自己找的一个不去研究此论文的接口,也是写下此篇文章的意义之一(万一有人提到了Bruijn Sequences
关键词,我们也不至于显得过分无知)。
math/bits包中的部分函数
如果有人知道这个包,那请原谅我的无知直接跳过本部分即可。老许发现这个包是源于ntz8tab
变量所在文件runtime/internal/sys/intrinsics_common.go
中的一句注释。
// Copied from math/bits to avoid dependence.
作为一个资深的CV工程师, 看到这句的第一反应就是我终于可以挺直腰杆了。适当Copy代码不丢人!
math/bits
这个包函数较多,老许挑几个介绍即可,其余的还请各位读者自行挖掘。
LeadingZeros(x uint) int
: 返回x所有高位为0的个数。
TrailingZeros(x uint) int
: 返回x最低位为0的个数。
OnesCount(x uint) int
:返回x中bit位为1的个数。
Reverse(x uint) uint
: 将x按bit位倒序后再返回。
Len(x uint) int
: 返回表示x的有效bit位个数(高位中的0不计数)。
ReverseBytes(x uint) uint
: 将x按照每8位一组倒序后返回。
将x逃逸至堆
// Dummy annotation marking that the value x escapes,
// for use in cases where the reflect code is so clever that
// the compiler cannot follow.
func escapes(x interface{}) {if dummy.b {dummy.x = x}
}var dummy struct {b boolx interface{}
}
老许是在reflect.ValueOf
函数中发现此函数的调用,当时就觉着挺有意思。如今再次回顾也依旧佩服不已。读书是和作者的对话,阅读源码是和开发者的对话,看到此函数就仿佛看到Go语言开发者们和编译器斗智斗勇的场景。
让出当前Processor
// Gosched yields the processor, allowing other goroutines to run. It does not
// suspend the current goroutine, so execution resumes automatically.
func Gosched() {checkTimeouts()mcall(gosched_m)
}
让出当前的Processor,允许其他goroutine执行。在实际的开发当中老许还未遇到需要使用此函数的场景,但多了解总是有备无患。
最后,衷心希望本文能够对各位读者有一定的帮助。
golang-math实用小技巧相关推荐
- 送你16个matplotlib绘图实用小技巧(附代码)
来源:雪山飞猪 本文约2800字,建议阅读10分钟 本文为你分享16个matplotlib绘图实用小技巧. 标签:数据分析 1. 添加标题-title import numpy as npimport ...
- VC的若干实用小技巧
Visual C++6.0(5.0)开发工具功能非常强大,但是对于初学者来说,却有很多细节的问题需要注意.作者搜集整理了以下一些实用小技巧,希望对初学者有所帮助. 1:使用vc开发项目时,常会遇到这种 ...
- 实用小技巧(一):UIScrollView中上下左右滚动方向的判断
https://www.jianshu.com/p/93e8459b6dae 2017.06.01 01:13* 字数 674 阅读 1201评论 0喜欢 1 2017.06.01 01:13* 字数 ...
- VC的若干实用小技巧 (如何干净的删除一个类)
Visual C++6.0(5.0)开发工具功能非常强大,但是对于初学者来说,却有很多细节的问题需要注意.作者搜集整理了以下一些实用小技巧,希望对初学者有所帮助. 1:使用vc开发项目时,常会遇到这种 ...
- 总结MySQL建表、查询优化实用小技巧
MySQL建表阶段是非常重要的一个环节,表结构的好坏.优劣直接影响着后续的管理维护,赶在明天上班前分享总结个人MySQL建表.MySQL查询优化积累的一些实用小技巧. 技巧一.数据表冗余记录添加时间与 ...
- mysql建表测试_总结MySQL建表、查询优化实用小技巧
MySQL建表阶段是非常重要的一个环节,表结构的好坏.优劣直接影响着后续的管理维护,赶在明天上班前分享总结个人MySQL建表.MySQL查询优化积累的一些实用小技巧. 技巧一.数据表冗余记录添加时间与 ...
- 20个你应该知道的iPhone 7实用小技巧
听说iOS 11马上就要发布,再过几个月新版iPhone8也即将上线,你真的会用你的iPhone7了吗?下面我们来介绍几个iPhone7的实用小技巧. 1.输入消息时的光标移动: 有很多新用户在疑惑输 ...
- 苹果手机计算机怎样拉到桌面,20个你应该知道的iPhone 7实用小技巧
本文由那年那个饭桶整理,未经作者授权,请勿转载,感谢您的尊重. 听说iOS11马上就要发布,再过几个月新版iPhone8也即将上线,你真的会用你的iPhone7了吗?下面我们来介绍几个iPhone7的 ...
- phpstudy mysql建表_MySQL_总结MySQL建表、查询优化的一些实用小技巧,MySQL建表阶段是非常重要的一 - phpStudy...
总结MySQL建表.查询优化的一些实用小技巧 MySQL建表阶段是非常重要的一个环节,表结构的好坏.优劣直接影响着后续的管理维护,赶在明天上班前分享总结个人MySQL建表.MySQL查询优化积累的一些 ...
- 微信公众号运营都有哪些实用小技巧,你学会了吗
移动媒体的发展,一些新媒体平台也变得热门起来,其原因人流量随之增长起来,像公众号.自媒体.短视频等,这些平台都是流量非常多的,公众号在微信刚出来的时候,还不怎么热门,也是近几年才受到企业受宠,很多企业 ...
最新文章
- matlab图像处理课程设计,基于MATLAB_GUI的数字图像处理程序设计课程设计
- python 判断节假日_[宜配屋]听图阁
- java开发书籍,送大厂面经一份!
- Hibernate各种主键生成策略与配置详解 - 真的很详细啊!!
- ISO 5 Lecture for Micro-Macro Interactions
- [react-router] 请你说说react的路由是什么?
- 计算机操作系统(3):操作系统的基本特征
- Python应该怎么去练习和使用
- 转: jvm调优参数总结
- 加州出台严格无人车路测新政:要求各公司尽快申请部署许可
- Apache logresolve命令
- SAP JCO3 官网代码解读 sap call java server
- 全电子计算机联锁厂家,传统计算机联锁与全电子计算机联锁对比分析
- 六、Prometheus+Grafana搭建监控系统
- 2407 · 计算 a + aa + aaa + aaaa 的值(LintCode,Python,入门)
- 张小龙回应一切!2019微信公开课一人撑到半夜,4小时演讲3万字实录
- 荣耀开发者关怀月邂逅1024程序员节,请开发者喝咖啡
- 有道翻译软件下载地址
- 【JDK7】新特性(5) fork/join 框架
- 2015 mbpr13 升级固态硬盘
热门文章
- 天蝎座性格最精确的解析
- 赛效:WPS何把文档里竖排的文字变成横排的
- mysql-5.5.20-winx64_mysql-5.7.20-winx64命令安装
- 基于STM32采集CO2(MH-Z19C)传感器数据
- 【渝粤教育】电大中专跨境电子商务理论与实务 (24)作业 题库
- hdu 1205 吃糖果(数学)
- win10模拟器(win10模拟器无限蓝卡)
- su切换为root并输入root密码确定正确但会有卡顿并提示su: Permission denied
- 镜湖资本吴幽:集齐这六颗钻石、你就能成为区块链领域的灭霸
- 字节跳动2018.11校招测试岗笔试(回忆版)