Java移位运算

博客理由:景区APP项目中涉及到分布式ID设计。分别有几种ID的设计方式:一种是数据库的自增,但是局限很大;第二种uuid,直接采用jdk自带的uuid生成即可;第三种是Twitter的Snowflake(雪花)ID生成技术,目前还在研究公开的源码,但是其中涉及到的移位运算比较多,故写下此文章回顾移位运算。

Java中有三种移位运算:

num << 位数    :这种表示num向左移动多少位,一般会用长整型来描述这个num,例如(Snowflake中的时间戳取值范围)1L << 41,就代表1L毫秒左移41位。

num >> 位数    :num右移具体位数;

>>>    : 无符号右移,忽略符号位,空位都以0补齐。

先来看一段移位的Demo,然后我来说明一下如何理解Java的移位运算。

package com.b510.test;

/**
 * @author 
 * @create date:2017-11-17
 * @version 1.0
 */
public class Test {

    public static void main(String[] args) {
        int number = 10;
        //原始数二进制
        printInfo(number);
        number = number << 1;
        //左移一位
        printInfo(number);
        number = number >> 1;
        //右移一位
        printInfo(number);
    }
    
    /**
     * 输出一个int的二进制数
     * @param num
     */
    private static void printInfo(int num){
        System.out.println(Integer.toBinaryString(num));
    }
}
运算结果:

1010
10100
1010
这就是移位运算的过程,其实对于Java语言来说,移位运算运用的并不是很多,因此移位运算对于大多数初级开发者来说会感觉到很陌生、很神秘。

我们应当这么理解Java中的移位运算:首先移位运算是针对二进制数来说的,由于Java中的整型(int long)都是以十进制表示,因此我们应当明确一点,一个数可以有多种进制的表达形式,我们写的整型数也同样可以进行移位运算,当然,移位之后的值,就必须去用二进制的思维去考虑了。

一种常见的应用场景是二进制数的取值范围,Snowflake中时间戳用41位的二进制表示,那41位的二进制数可以表示多少个1毫秒呢?计算的方式就是1L << 41,其实这个运算可以拆分成两部分:第一部分1L,第二部分<<41,第一部分代表十进制的1(个)毫秒,第二部分左移41位,实际上在Java底层会将前面的1L转换成二进制数之后再进行移位运算,最后将结果以长整型的形式输出出来。

可以用十进制来类比一下,一个十进制的1左移3位是多少?没错,是1000,取值范围是1~999(一般计算的是整数的取值)。

这样我们就可以理解:为什么Snowflake的41位的时间戳可以用:(1L<< 41) / (1000L * 60 * 60 * 24 * 365) = 69年了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值