首先需要提醒的是这条语句是有语言平台局限性的,在C语言、Python、Java等语言是无法进行浮点数位运算的,因为位运算只能是整型。
但你会发现在JavaScript中却可以执行这条语句:
首先我们需要了解一些知识点:
1.单双精度分别对应于编程语言当中的float和double类型。其中float是单精度的,采用32位二进制表示,其中1位符号位,8位阶码以及23位尾数。double是双精度的,采用64位二进制表示,其中1位符号位,11位阶码以及52位尾数,js中的浮点数就是双精度的。
2.JavaScript采用的IEEE754标准作为数字存储标准,IEEE754规定双精度数值以64位存储,其中1位为符号位,11位为指数位,剩余52位为尾数位。
3.JavaScript的位运算以32位二进制执行,进行位运算时,先将数值转换成32位有符号整数
上面说的32位应该是包含1位符号位的,像下面直接拿32位二进制进行或运算就出现异常了:
4.位运算,这里简单讲一下或运算其他自行补充,关于或运算即先将数值转成二进制再或运算,而或运算规则是一个为1,其值为1:0|0=0; 0|1=1; 1|0=1; 1|1=1;
知道上面这些知识点就可以开始解释(((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)了:
Math.random()是生成随机数。
0x10000:以0x开始的数据表示16进制,10000转成十进制数就是65536,实际上这是为了后面获取四位数随机号码所以乘以10000,而为了获取包含字母在内的字符就用16进制。
|0是或运算,从上面可以得知或运算会转换成32位整数,而任何数或0都等于本身,实际上这一步就是为了取整。
toString(16):即number.toString(radix),把数字转换为字符串,参数radix可选 2 ~ 36 之间的整数,即表示用哪个进制值显示,toString(16)就是转成16进制的字符串。
substring(1) :stringObject.substring(start,stop) 方法用于提取字符串中介于两个指定下标之间的字符,其中start起始索引(包括)从 0 开始、stop结束索引(不包括),substring(1) 就是从第2个位置开始截取。
整个解释起来就是:(1 + Math.random()) 结果是1点几数值,1点几*0x10000结果就是一个五位整数加小数的数值,再|0就是取整数,到这里就得到一个五位数数值了,再toString(16)就是换成五位数字符串,再substring(1)就是从第2个位置开始截取,最后就得到一个四位数的随机字符串。
最后说说存在的问题,首先这个语句可读性低,估计很多人第一眼看一脸懵逼,不利于维护,其次丢失高位数据,原本52(或53)位的数据,被舍弃掉高位的21(或22位)的数据,非常危险,所以不大建议这么干,可能很多人会用这个去生成验证码、UUID这问题倒不大,总之还是慎用这个东西为好啊。
展开阅读全文
上一篇: 关于我的分享录安卓端APP下载安装教程