java 左移 返回值_java左移右移运算符详解

在阅读源码的过程中,经常会看到这些符号<< ,>>,>>>,这些符号在Java中叫移位运算符,在写代码的过程中,虽然我们基本上不会去写这些符号,但需要明白这些符号的运算原理,比如HashMap中有以下代码:

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//左移

static final int hash(Object key) {

int h;

return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//无符号右移

}

上段代码中就包含左移运算符<>>。这篇文章详细说一下这三个符号:

1、左移运算符:<<

先随便定义一个int类型的数int,十进制的value = 733183670,转换成二进制在计算机中的表示如下:

01c4bd3fa4121318cf142171f4bbe64e.png

value << 1,左移1位

0d2a67366ae27986009057cb0843dcaa.png

左移1位后换算成十进制的值为:1466367340,刚好是733183670的两倍, 有些人在乘2操作时喜欢用左移运算符来替代。

value << 8,左移8位看一下:

552f04dc0687133163191229c14bfc2e.png

左移8位后变成了十进制的值为:-1283541504,移动8位后,由于首位变成了1,也就是说成了负数,在使用中要考虑变成负数的情况。

根据这个规则,左移32位后,右边补上32个0值是不是就变成了十进制的0了?答案是NO,当int类型进行左移操作时,左移位数大于等于32位操作时,会先求余(%)后再进行左移操作。也就是说左移32位相当于不进行移位操作,左移40位相当于左移8位(40%32=8)。当long类型进行左移操作时,long类型在二进制中的体现是64位的,因此求余操作的基数也变成了64,也就是说左移64位相当于没有移位,左移72位相当于左移8位(72%64=8),写一段代码来测试一下

int intValue = 733183670;//随意写一个数

System.out.println("intValue:" + (intValue));//打印intValue

System.out.println("intValue左移1位:" + (intValue << 1));//左移1位

System.out.println("intValue左移8位:" + (intValue << 8));//左移8位

//当int类型左移位数大于等于32位操作时,会先求余后再进行移位操作

System.out.println("intValue左移32位:" + (intValue << 32));//求余为32%32=0,相当于左移0位(不移位)

System.out.println("intValue左移40位:" + (intValue << 40));//求余为40%32=8,相当于左移8位

System.out.println("intValue左移64位:" + (intValue << 64));//求余为64%32=0,相当于左移0位(不移位)

long longValue = 733183670L;

System.out.println("longValue:" + (longValue));//打印longValue

System.out.println("longValue左移1位:" + (longValue << 1));//左移1位

System.out.println("longValue左移8位:" + (longValue << 8));//左移8位

//当long类型左移位数大于等于64位操作时,会先求余后再进行移位操作

System.out.println("longValue左移64位:" + (longValue << 64));//求余为64%64=0,相当于左移0位(不移位)

System.out.println("longValue左移72位:" + (longValue << 72));//求余为72%64=8,相当于左移8位

System.out.println("longValue左移128位:" + (longValue << 128));//求余为128%64=0,相当于左移0位(不移位)

看一下结果:

b3de0617af0390de90f0e096b97e675a.png

由于double,float在二进制中的表现比较特殊,因此不能来进行移位操作,报错,编译不过,如下图:

d80993913fee25b0e73a571cfbac8899.png

注意:其它几种整形byte,short移位前会先转换为int类型(32位)再进行移位,这里就不写代码测试了,大家有兴趣可自行测试。

综上所述:左移 << 其实很简单,也就是说丢弃左边指定位数,右边补0。

2、右移运算符:>>

还是这个数:733183670

cd91a04f9be4175f73a1b10ba09b6f56.png

value >> 1,右移1位

55bacf0979de04e58eeb677f66d89a9b.png

右移1位后换算成十进制的值为:366591835,刚好是733183670的1半, 有些人在除2操作时喜欢用右移运算符来替代

value >> 8,右移8位看一下

16ed56ffb5f1721178d42015f5c8a2fb.png

写一段代码测试一下

int intValue = 733183670;//随意写一个数

System.out.println("intValue:" + (intValue));//打印intValue

System.out.println("intValue右移1位:" + (intValue >> 1));//右移1位

System.out.println("intValue右移8位:" + (intValue >> 8));//右移8位

//当int类型右移位数大于等于32位操作时,会先求余后再进行移位操作

System.out.println("intValue右移32位:" + (intValue >> 32));//求余为32%32=0,相当于右移0位(不移位)

System.out.println("intValue右移40位:" + (intValue >> 40));//求余为40%32=8,相当于右移8位

System.out.println("intValue右移64位:" + (intValue >> 64));//求余为64%32=0,相当于右移0位(不移位)

long longValue = 733183670L;

System.out.println("longValue:" + (longValue));//打印longValue

System.out.println("longValue右移1位:" + (longValue >> 1));//右移1位

System.out.println("longValue右移8位:" + (longValue >> 8));//右移8位

//当long类型右移位数大于等于64位操作时,会先求余后再进行移位操作

System.out.println("longValue右移64位:" + (longValue >> 64));//求余为64%64=0,相当于右移0位(不移位)

System.out.println("longValue右移72位:" + (longValue >> 72));//求余为72%64=8,相当于右移8位

System.out.println("longValue右移128位:" + (longValue >> 128));//求余为128%64=0,相当于右移0位(不移位)

结果:

8f5e628d4b63570e4737a243fb90a69a.png

和左移一样,int类型移位大于等于32位时,long类型大于等于64位时,会先做求余处理再位移处理,byte,short移位前会先转换为int类型(32位)再进行移位。以上是正数的位移,我们再来看看负数的右移运算,如图,负数intValue:-733183670的二进制表现如下图:

8bef038e6d9fc7dcb36893c910676e10.png

右移8位,intValue >> 8

a4d3317389c8120fe09e816fac2d73c8.png

综上所述:右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上符号位。

3、无符号右移运算符:>>>

无符号右移运算符>>>和右移运算符>>是一样的,只不过右移时左边是补上符号位,而无符号右移运算符是补上0,也就是说,对于正数移位来说等同于:>>,负数通过此移位运算符能移位成正数。以-733183670>>>8为例来画一下图

062c0081470fc8546407be6346df1be8.png

无符号右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上0。

摘自https://zhuanlan.zhihu.com/p/30108890

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人与人的差距在于认知

作者介绍findyi&#xff0c;腾讯、360码农&#xff0c;前哒哒少儿英语技术VP&#xff0c;现任土豆教育CTO。工作和生活中不光要埋头干活&#xff0c;还要抬头看天。思考总结方法论是提升认知的必备途径&#xff0c;是将碎片化知识总结为动态的智慧的过程。认知有多重要&#xf…

《C++ Primer》14.3节练习

练习14.13: 对于Sales_data类&#xff0c;其实我们并不需要再为它添加其他算术运算符。但是这里我们可以考虑为它实现一个减法运算符。 class Sales_data {friend Sales_data operator-(const Sales_data &lhs,const Sales_data &rhs);public:Sales_data&operator…

C# lock 语法糖实现原理--《.NET Core 底层入门》之自旋锁,互斥锁,混合锁,读写锁...

在多线程环境中&#xff0c;多个线程可能会同时访问同一个资源&#xff0c;为了避免访问发生冲突&#xff0c;可以根据访问的复杂程度采取不同的措施原子操作适用于简单的单个操作&#xff0c;无锁算法适用于相对简单的一连串操作&#xff0c;而线程锁适用于复杂的一连串操作原…

《C++ Primer》14.3.1节练习

练习14.16: //为strBlob定义和! class strBlob {friend bool operator(const strBlob &lhs,const strBlob &rhs);friend bool operator!(const strBlob &lhs,const strBlob &rhs); };bool operator(const strBlob &lhs,const strBlob &rhs) {return l…

java中employee_java Employee(雇员)

public class Employee {//类Employee有两个属性,name,sexString name;char sex;Employee(String n,char s){//用new使用时构造该类&#xff0c;把n,s分别赋值namen;sexs;}public String getName(){//获取namereturn name;}public char getSex(){//获取sexreturn sexl;//你这里…

.NET5来了你别慌

近日微软.Net大咖Scott在博客中对外宣传.NET5首个预览版&#xff0c;并且我们可以通过微软的官网下载SDK5和运行库。很多朋友感觉.NetCore3.1还没搞明白&#xff0c;.NET5就来了感觉一下子慌了神。在这里我提醒朋友们&#xff0c;瞬息万变的世界中&#xff0c;总有相对不变的真…

《C++ Primer》14.3.2节练习(部分)

练习14.18: String类的关系运算符就是比较两个字符串字典序的先后。 class String {friend bool operator<(const String &s1,const String &s2);friend bool operator<(const String &s1,const String &s2);friend bool operator>(const String &am…

java8 stream 最大值_JDK8-Stream流常用方法

Stream流的使用流操作是Java8提供一个重要新特性&#xff0c;它允许开发人员以声明性方式处理集合&#xff0c;其核心类库主要改进了对集合类的 API和新增Stream操作。Stream类中每一个方法都对应集合上的一种操作。将真正的函数式编程引入到Java中&#xff0c;能 让代码更加简…

周三晚6点半!盛派首席架构师“苏老师”在线解密内部系统框架!

工作中有些事&#xff0c;看起来只用一会会儿就能完成&#xff0c;但真正完成起来&#xff0c;总会遇到一些意想不到的困难&#xff01;你一定碰到过这样的情况——开发时间 2 周的项目&#xff0c;搭框架就要用 1 周&#xff0c;刚开发完&#xff0c;各种调试和修 bug又花去 2…

《C++ Primer》14.4节练习(部分)

练习14.20: class Sales_data {friend Sales_data operator(const Sales_data &lhs,const Sales_data &rhs);public:Sales_data &operator(const Sales_data &rhs); }Sales_data operator(const Sales_data &lhs,const Sales_data &rhs) {Sales_data …

java 二维高斯_Java Random nextGaussian()用法及代码示例

随机类的nextGaussian()方法返回下一个伪随机数&#xff0c;即与随机数生成器序列的平均值为0.0&#xff0c;标准差为1.0的高斯(正态)分布双精度值。用法:public double nextGaussian()参数&#xff1a;该函数不接受任何参数。返回值&#xff1a;此方法返回平均值为0.0&#xf…

给微软的日志框架写一个基于委托的日志提供者

动手造轮子&#xff1a;给微软的日志框架写一个基于委托的日志提供者Intro微软的日志框架现在已经比较通用&#xff0c;有时候我们不想使用外部的日志提供者&#xff0c;但又希望提供一个比较简单的委托就可以实现日志记录&#xff0c;于是就有了后面的探索和实现。Solution基于…

C++分析使用拷贝控制成员和调用构造函数的时机

我们来分析下面这段代码&#xff1a; #include <iostream> #include <vector>using namespace std;struct X {X() {cout << "构造函数X()" << endl;}X(const X &) {cout << "拷贝构造函数X(const X&)" << en…

mybatis mysql模糊查询_详解MyBatis模糊查询LIKE的三种方式

模糊查询也是数据库SQL中使用频率很高的SQL语句&#xff0c;使用MyBatis来进行更加灵活的模糊查询。直接传参法直接传参法&#xff0c;就是将要查询的关键字keyword,在代码中拼接好要查询的格式&#xff0c;如%keyword%,然后直接作为参数传入mapper.xml的映射文件中。public vo…

《C++ Primer》13.1.4节练习

练习13.14: 这是一个典型的应该定义拷贝控制成员的场合。如果不定义拷贝构造函数和拷贝赋值运算符&#xff0c;依赖合成的版本&#xff0c;则在拷贝构造和赋值时&#xff0c;会简单复制数据成员。对本问题来说&#xff0c;就是将序号简单复制给新对象。 因此&#xff0c;代码中…

十问十答 CDDL 许可证

今天我们来整理一下通用开发和发行许可证 CDDL 的十大问题清单。通用开发与发行许可证&#xff08;Common Development and Distribution License&#xff0c;CDDL&#xff09;由已被甲骨文公司收购的太阳微系统公司&#xff08;Sun Microsystems&#xff09;发布的一种开源许可…

浅谈java spring_浅谈Spring(一)

Spring是当前比较流行的基于Java语言的MVC框架,所谓框架也就是它已经实现好了诸多东西,使java开发人员能把精力尽量放在业务逻辑上.Spring技术的特点是IOC, 即反向注入,主要应用的是XML技术和POJO(简单Java对象),Spring要达到的目的其实很简单,就是尽量简化原来Java中的地层数据…

Http Server API路由请求到web程序

引言接上文&#xff0c;容器内web程序一般会绑定到http://0.0.0.0:{某监听端口}或http://:{某监听端口}&#xff0c;以确保使用容器IP可以访问到web应用。正如我们在ASP.NET Core官方镜像显示的&#xff0c;ASP.NET Core程序在容器内80端口监听请求This image sets the ASPNETC…

mysql 多行拼接注入_MySQL注入汇总

Mysql注释符&#xff1a;单行注释&#xff1a; # 在对URL使用过程中可能遇到Unicode编码问题&#xff0c;可常用%23代替多行注释&#xff1a;/**/单行注释&#xff1a; -- 此处需要注意后面存在空格&#xff0c;否则报错0.万能密码(基于SQL验证&#xff0c;SQL注入)aaa or 1#aa…

《C++ Primer》13.1.6节练习(部分)

练习13.18: #include <iostream> #include <string> using namespace std;class Employee {private:static int sn;public:Employee() {mysn sn;}Employee(const string &s) {name s;mysn sn;}const string &get_name() {return name;}int get_mysn() …