`
uule
  • 浏览: 6357137 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

JAVA中位运算与逻辑运算

 
阅读更多

问题一: 
JAVA中&&和&、||和|(短路与和逻辑与、短路或和逻辑或)的区别? 


首先名称是不同的 
&&逻辑与  ||逻辑或  它们都是逻辑运算符 
& 按位与  | 按位或  它们都是位运算符 
if(a==1&&b==2) 这是说既要满足a=1也要满足b=2 
if(a==1||b==2) 这是说或者满足a=1或者要满足b=2 
而a&b或者a|b则是二进制的与或运算 
&同为1时为1,否则为0 
|同为0时为0,否则为1 
3&5则 
 0011 
&0101 
 0001 
等于1 

3|5则 
 0011 
|0101 
 0111 
等于7 

&&逻辑与 也叫做短路与 因为只要当前项为假,它就不往后判断了,直接认为表达式为假 
||逻辑或 也叫做短路或 因为只要当前项为真,它也不往后判断了,直接认为表达式为真 

问题二: 
关于Java 中逻辑运算与位运算的区别(具体到解一道题) 
题目出自Java2实用教程(第三版)(却没有解释) 
程序如下图: 
运行结果如下: 
为什么? x,y,a,b 不是都在IF语句里都重新赋值了吗?按道理全为真了,y也该是20了吧?(用程序验证过了,的确是这个结果) 


回答: 
逻辑运算符执行的是短路求值 
所谓短路,就是当参与运算的一个操作数已经足以推断出这个表达式的值的时候,另外一个操作数(有可能是表达式)就不会执行 

比如: 
static boolean f1() { System.out.println( "function f1 called." ); return true; } 
static boolean f2() { System.out.println( "function f2 called." ); return false; } 
if ( false && f1() ) {} // f1不会被调用 
if ( true || f2() ){} // f2不会被调用 

由于&& 要求它的参与操作的两个操作数都是布尔值真,才得真,所以只要得出其中一个为假,那么另一部分的表达式就不会被求值(在上面的例子中是f1()不会被调用) 
同理由于||要求它的参与操作的两个操作数只要其中之一为真,就得真,所以只要得出其中一个为真,那么另一部分也不会被求值(在上面的例子中是f2()不会被调用) 

这就是逻辑操作符所谓的“短路求值” 
位操作没有这一特性,所以不管那边的值是如何,任何参与运算的表达式都会被执行求值,因此也就产生了你代码之中的结果了。 

三、Java中逻辑运算短路的理解: 
短路” 主要用于逻辑运算符中,即 “ !   && || "这三种运算符 
短路 就是知如果左侧的表达式能确定运算后的结果,则不再计算右侧的表达式。 
如(1>2)&&(2<3)   明明左侧已经为假 了   ,我 不用计算右侧我一定知道 此表达是为假,这样 就好似物理中的电流,当某处短路时,电流直接从一条路通过,而不再管另一条路。 

来源:http://forrest420.iteye.com/blog/1075497

 

 ================================================================================

 源码中:   

 // 本来可以简单地写成head-1,但如果head为0,减1就变为-1了,和elements.length - 1进行与操作就是为了处理这种情况,这时结果为elements.length - 1。  
    elements[head = (head - 1) & (elements.length - 1)] = e;  

 

简单点说:内存中有16位,分为高8位和低8位

255:00000000 11111111

xxx: 00110101 01010101

其作用是对低位清零,保留高位,或者是查看是否有进位,这都是些底层的东西,你想了解更多,可以先了解汇编语言。

正常编程时不需要这么写,如果你非要这么写,会影响你编程的速度,但是会极大的提高程序运行的速度。(要知道“加减乘除”最终都要被转换为“与或非”)

 

  ================================================================================

JAVA位预算:

<1>.在了解位移之前,先了解一下正数和负数的二进制表示形式以及关系:
举例15和-15:

15 的原码: 00000000 00000000 00000000 00001111 
    补码: 11111111 11111111 11111111 11110000
                 +1 = 
-15的原码:11111111 11111111 11111111 11110001

负数的原码即为:正数的原码取反,再加1。

<2>位移操作:(只针对 int类型的数据有效,java中,一个int的长度始终是32位,也就是4个字节,它操作的都是该整数的二进制数).也可以作用于以下类型,即 byte,short,char,long(当然,它们都是整数形式)。当为这四种类型是,JVM先把它们转换成int型再进行操作

<<     左移   
>>     右移
>>>    无符号右移

<< 和>>为数值位移,>>>为逻辑位移。【注】:Java中不存在<<<。

$1> m<<n的含义:把整数m表示的二进制数左移n位,高位移出n位都舍弃,低位补0.  (此时将会出现正数变成负数的形式)
实例:
  3<<2剖析:
  3二进制形式: 00000000 00000000 00000000 00000011,按照$1的原理,得到00000000 00000000 00000000 00001100,即为12. 
  
  左移使整数变为负数:
  10737418<<8
  10737418二进制表示形式:00000000 10100011 11010111 00001010,按照$1的原理,得到10100011 11010111 00001010 00000000,即为:-1546188288.

$2> m>>n的含义:把整数m表示的二进制数右移n位,m为正数,高位全部补0;m为负数,高位全部补1.
实 例: 
  3>>2剖析:
  3二进制形式: 00000000 00000000 00000000 00000011,按照$2的原理,得到00000000 00000000 00000000 00000000,即为0.
  -3>>2剖析:
  -3二进制形式: 11111111 11111111 11111111 11111101,按照$2的原理,得到11111111 11111111 11111111 11111111,即为-1.

以上:每 个整数表示的二进制都是32位的,如果右移32位和右移0位的效果是一样的。依次类推,右移32的倍数位都一样。

备注:对于右移32位右移0位是结果是一样的,我一直不能够理解。现在我只能理解为32比较特殊。相当于整体全移。移0位相同。左移也是一样的。


$3> m>>>n:整数m表示的二进制右移n位,不论正负数,高位都补零。
实例: 
  3>>>2剖析:
  3二进制形式: 00000000 00000000 00000000 00000011,按照$3的原理,得到00000000 00000000 00000000 00000000,即为0.
  -3>>>2剖析:
  -3二进制形式: 11111111 11111111 11111111 11111101,按照$3的原理,得到00111111 11111111 11111111 11111111,即为1073741823.
   

【注】:对于$1,$2,$3,如果n为负数:这时JVM会先让n对32取模,变成一个绝对值小于32的负数,然后再加上32,直到 n 变成一个正数。
实例:
   4<<-10
   4的二进制形式:00000000 00000000 00000000 00000100,-10对32取模再加上32,不用说了,得到22,则4<<-10,即相当于4<<22。
   此时按照再按照$1原理,得到00000001 00000000 00000000 00000000,得到的即为:16777216。

OK, 大功告成。

综上所述:
   m<<n即在数字没有溢出的前提下,对于正数和负数,左移n位都相当于m乘以2的n次方.
   m>>n即相当于m除以2的n次方,得到的为整数时,即为结果。如果结果为小数,此时会出现两种情况:(1)如果m为正数,得到的商会无条件 的舍弃小数位;(2)如果m为负数,舍弃小数部分,然后把整数部分加+1得到位移后的值。
 

---------------------------------------------------------------------------------


接 下来在此说说操作的好处,速度超快,这些都是底层的二进制机器操作指令。
  比如:a*2,

       1.jvm先为变量a分配空间;

       2.再进行a*2的操作

      3.再把结果返回给相应的变量。
而 a<<1,和a*2一样,它只需要一条指令即可,速度很快。当然前三种位移操作都是对2的倍数

进行操作时可用。



再 进行些许补充,谈到位操作,当然还要说到四个操作符:~(按位非),|(按位或),&(按位

),^(按位异或),这些都是大学 计算机基础用法,对整数的二进制形式进行操作,然后再

转换为整数,具体操作如下。
1.~(按位非):【解义】对该整数的二进制形 式逐位取反。
    ~4:(一元操作符)
     4的二进制形式为:00000000 00000000 00000000 00000100,逐位取反后得

到:11111111 11111111 11111111 11111011,即为-5.
2.| (按位或):【解义】对两个整数的二进制形式逐位进行逻辑或运算,原理为:1|0=1,0|0=0,1|1=1,0|1=1
等。
    4|-5:
     4的二进制形式为:00000000 00000000 00000000 00000100,
    -5的二进制形式为:11111111 11111111 11111111 11111011,
  逐位进行逻辑或运算:11111111 11111111 11111111 11111111,即得到-1.
3.&(按位):【解义】对两个整数的二进制形式逐位进行逻辑 运算,原理:1|0=0,0|0=0,1&1=1;0&1=0等。  
   4&-5:
     4的二进制形式为:00000000 00000000 00000000 00000100,
    -5的二进制形式为:11111111 11111111 11111111 11111011,
  逐位进行逻辑运算:00000000 00000000 00000000 00000000,即得到0.  

实际应用:可以把字节转换为整 数,-64&0xFF=192,也可以用八进制的形式,-64&0377=192、

其实0xFF和0377都表示的是整数255、 
4.^(按 位异或):【解义】对两个整数的二进制形式逐位进行逻辑异或运算,原理:1^1=0,1^0=1,0^1=1,0^0=0.
   4^-5:
     4的二进制形式为:00000000 00000000 00000000 00000100,
    -5的二进制形式为:11111111 11111111 11111111 11111011,
逐位进行逻辑异或运算:11111111 11111111 11111111 11111111,即得到-1.

实际应用:按位异或可以比较两个数字是否相等,它利用 1^1=0,0^0=0的原理。  20^20==0

转自:http://aokunsang.javaeye.com/blog/615658

关于二进制一些说明:

关于负数的二进制表示方法

今天知道了对于负数的二进制方法的表示方法:例如 -5   
第一步:首先要把5变成101的二进制形式
第二步:再者就是按位取反,(形 成前面全是1)010
第三步:在最后加1 形成:11111111 11111111 11111111 11111011
反过来如果把 最高位是1的二进制变成负的整形时
第一步:位取反,变成00000000 00000000 00000000 00000100
第二 步:在最低位加上1,形成101
第三步:形成整形5 ,在加上负号;
java中怎么用代码实现二进制于十进制的转化
public int binaryInToInt(String str)
{
             int j=0,i=0;
            char c;
            for(i=0;i<str.length();i++)
             {
                      if(str.charAt(str.length()-i)=='1')
                        {
                                     j=j+exp(2*ln(str.length()-i));
                        }
 
             }
return j;

转自:
http://blog.csdn.net/zdp5528/archive/2008/04/10/2278719.aspx

(1)正负表示方法
用字节的最高位表示:"1"表示"正","0"表示"负"

(2)计算机中数字是以哪个码储存的?
补码

(3) 负数 的二进制补码转换成十进制的方法
1、把补码“取反”(把二进制数的各位“1”换“0”,“0”换“1”。比如“101010”取反后为“010101”)
2、把取反后的二进制数“加1”
3、最后用常规的方法把“加1”后的二进制数转换为十进制数 

将负数转换为二进制

http://blog.csdn.net/onewalkingman/archive/2009/01/10/3746154.aspx

我们已经知道计算机中,所有数据最终都是使用二进制数表达。

我们也已经学会如何将一个10进制数如何转换为二进制数。

不过,我们仍然没有学习一个负数如何用二进制表达。

比如,假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:

00000000 00000000 00000000 00000101

5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。

现在想知道,-5在计算机中如何表示? 

在计算机中,负数以其正值的补码形式表达。

什么叫补码呢?这得从原码,反码说起。

原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。

比如 00000000 00000000 00000000 00000101 是 5的 原码。 

反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。

取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)

比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。

称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反码。

反码是相互的,所以也可称:

11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互为反码。

补码:反码加1称为补码。

也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。

比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。

那么,补码为:

11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。
再举一例,我们来看整数-1在计算机中如何表示。

假设这也是一个int类型,那么:
1、先取1的原码:00000000 00000000 00000000 0000000111111111 11111111 11111111 11111110

2、得反码:     11111111 11111111 11111111 11111110

3、得补码:     11111111 11111111 11111111 11111111

可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF

个人总结:
补码:反码加1称为补码。

一个负二进制转为十进制
例如:11111111 11111111 11111111 11111110
第一步:减1 变为11111111 11111111 11111111 11111101(二进制,第一位不足时从第二位第一也为2)
第二步:取反 00000000 00000000 00000000 00000010
根据常用方法转为十进制.最后要加-号
关于java中的~按位非
如:~1 
1二进制为 00000000 00000000 00000000 00000001
~1为:        11111111 11111111 11111111 11111110
首位为1说明此数为-根据上面的计算方法,即可以计算出结果。

分享到:
评论

相关推荐

    Java中的位运算

    ### Java中的位运算 #### 一、概述 位运算(Bitwise Operators)是计算机科学...通过上述示例和解释,我们可以看到位运算在Java中的应用及其背后的逻辑。理解这些基础知识对于深入学习Java以及优化代码具有重要意义。

    位运算课件(java学习位运算课件)

    在Java中,位运算主要包括按位与(&),按位或(|),按位异或(^),按位非(~),左移(),右移(&gt;&gt;)和无符号右移(&gt;&gt;&gt;). 这些运算符可以在整型变量之间进行,用于直接操作它们的二进制表示。例如,按位与运算符"&"用于两个位...

    能够实现逻辑运算(逻辑非、逻辑加、逻辑乘、逻辑异)、定点整数的单符号位补码加减运算、定点整数的原码一位乘法运算和浮点数的加减运算

    能够实现逻辑运算(逻辑非、逻辑加、逻辑乘、逻辑异)、定点整数的单符号位补码加减运算、定点整数的原码一位乘法运算和浮点数的加减运算。

    Java位运算和逻辑运算的区别实例

    在Java编程语言中,位运算和逻辑运算都用于处理布尔值和整数,但它们在实际操作和行为上有着显著的差异。理解这些差异对于优化代码和深入理解计算机底层工作原理至关重要。 首先,我们来看看逻辑运算符。逻辑运算符...

    Java 中的位运算

    ### Java中的位运算知识点 #### 一、位运算概述 位运算是计算机科学中的一个基本概念,它直接针对二进制位进行操作。在Java语言中,提供了多种位运算符来处理二进制数据,这对于优化算法性能、提高程序效率等方面...

    JAVA位运算.pdf

    本文将深入探讨Java中的位运算,包括位运算符、它们的工作原理以及在实际编程中的应用。 #### 位运算符及其功能 Java提供了多种位运算符,用于对整数类型的位进行操作。这些类型包括`long`、`int`、`short`、`char...

    十六进制字符串按位异或运算工具和java位异或运算

    在计算机科学中,十六进制(Hexadecimal)是一种逢16进1的进位制,通常用于表示二进制数据,因为每个十六进制数字可以代表4...通过理解其原理并掌握在Java中的实现方式,我们可以更有效地解决各种与位运算相关的问题。

    Java运算案例(算数运算+赋值运算+逻辑运算+关系运算+自增运算+自减运算+条件运算+位运算)

    在本案例中,我们将深入探讨八大类运算符:算数运算、赋值运算、逻辑运算、关系运算、自增运算、自减运算、条件运算以及位运算。这些运算符在编写Java代码时频繁使用,理解并熟练掌握它们对于编写高效、简洁的程序至...

    java二进制运算器(加、见、乘、除)

    6. **Java中的位运算符**: Java提供了多种位运算符,包括按位与(&),按位或(|),按位异或(^),左移(),右移(&gt;&gt;或&gt;&gt;&gt;),以及按位非(~)。这些运算符在处理二进制数据时非常有用。 7. **二进制转换**: 在Java中,我们...

    java位运算.docx

    位运算在现代Java编程中并不常用,但在某些特定场景下,如低级内存操作、并发控制(如`AtomicInteger`的`getAndSet()`方法)、数据编码解码、高效计算等,位运算仍然发挥着重要作用。理解并熟练掌握位运算,能够帮助...

    Java生成算数运算中文图片验证码

    总结起来,Java生成算数运算中文图片验证码的技术要点包括:随机算术表达式的生成、图像的绘制与扭曲、服务器端的验证逻辑以及项目组织结构的设计。这种验证码机制结合了语言和数学,既增加了安全性,又保持了用户...

    java表达式计算支持自定义运算

    // 在这里实现自定义运算逻辑 } } ``` 3. **构建表达式解析器**:为了处理包含自定义运算符的表达式,我们需要构建一个表达式解析器。解析器负责读取输入的字符串表达式,识别其中的运算符和操作数,并调用对应的...

    java位运算大全.pdf

    Java位运算大全涵盖了Java中位运算的基本概念、运算符以及其应用。位运算是一种直接对整数型数据的二进制位进行操作的运算,它可以用于高效地处理数据,尤其在系统底层开发和算法设计中至关重要。 首先,位运算的...

    java实现的XP系统下自带的计算器,包括括号的实现,逻辑运算的实现、所有算数运算的实现等。科学性和标准型计算器都实现了。等

    逻辑运算的实现则涉及到Java中的布尔类型和逻辑运算符,如`&&`、`||`、`!`等。逻辑运算通常与条件判断和流程控制紧密相关,开发者需要理解这些运算符的工作原理,以便正确地评估逻辑表达式的结果。 在科学计算模式...

    java 位运算知识

    Java 位运算是编程语言中的一种底层操作,它允许我们直接对整数类型的数据进行按位操作,包括按位与(&)、按位或(|)、按位异或(^)、按位非(~)以及左移()、右移(&gt;&gt;)和无符号右移&gt;&gt;&gt;。这些操作在处理二进制数据、优化...

    Java 中的位运算 .doc

    Java中的位运算是一种底层操作,它直接在二进制位级别上进行操作,这对于处理整数和优化代码性能特别有用。位运算符包括移位运算符和逻辑运算符。 移位运算符主要有三种: 1. **右移运算符 (&gt;&gt;)**: 将数值的二进制...

    普元EOS简单运算逻辑的编写

    在这个主题中,我们将深入探讨如何在EOS平台上利用Java进行简单的运算逻辑编写。 首先,我们需要理解EOS的基础架构。EOS通常采用组件化开发模式,Bizlet是EOS中的一个核心组件,用于封装业务逻辑。Bizlet类似于MVC...

    java中的位运算.doc

    Java中的位运算主要涉及到对整数类型的二进制数进行的操作,这些操作包括逻辑运算和移位运算。在Java中,所有的整数类型(如int和long)都是以二进制补码形式存储的,其中最高位是符号位,0表示正数,1表示负数。 1...

    JAVA中位运算符合移为运算符

    在阅读《JAVA中位运算符和移位运算符.docx》文档后,您将能更深入地理解这些运算符的实际应用和潜在的陷阱。无论是学习源码解析还是使用相关工具,掌握这些知识都将对您的Java开发工作大有裨益。

Global site tag (gtag.js) - Google Analytics