首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是按位运算符还是逻辑运算符?

是按位运算符还是逻辑运算符?
EN

Stack Overflow用户
提问于 2012-07-22 13:36:19
回答 4查看 3.1K关注 0票数 3

首先我知道&|^是按位运算符,现在有人把它们和&&||一起称为逻辑运算符,我完全搞混了--同一个运算符有两个名字?已经有逻辑运算符&&||,为什么还要使用&|^

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-07-22 13:43:22

Java运算符&|^要么是按位运算符,要么是逻辑运算符...取决于操作数的类型。如果操作数是整数,则运算符是按位的。如果它们是布尔值,那么运算符就是逻辑的。

这并不是我一个人说的。JLS也以这种方式描述这些运算符;请参阅JLS 15.22

(这就像+,意思是加法或字符串连接...取决于操作数的类型。或者就像“玫瑰”,意思是一朵花或一个淋浴附件。或者“猫”,意思是毛茸茸的动物或者UNIX命令。单词在不同的上下文中有不同的含义。编程语言中使用的符号也是如此。)

已经有逻辑运算符&&||了,为什么还要用&|^

在前两种情况下,这是因为操作符对于何时/是否计算操作数具有不同的语义。这两种不同的语义在不同的情况下是需要的;

代码语言:javascript
复制
    boolean res = str != null && str.isEmpty();

对比

代码语言:javascript
复制
    boolean res = foo() & bar();  // ... if I >>need<< to call both methods.

^运算符没有短路等效项,因为它根本没有意义。

票数 20
EN

Stack Overflow用户

发布于 2012-07-23 19:35:09

有一个语言参考是一回事,正确地解释它是另一回事。

我们需要正确地解释事物。

即使Java证明了&既是按位的,又是逻辑的,我们也可以说,&从远古时代起就没有失去其逻辑运算符的魔力,因为C。也就是说,&首先是一个内在的逻辑运算符(尽管它是一个非短路的运算符)。

&将lexically+logically解析为逻辑操作。

为了证明这一点,这两行代码的行为是相同的,从C到现在(Java、C#、PHP等)。

代码语言:javascript
复制
if (a == 1 && b)

if (a == 1 & b)

也就是说,编译器会将它们解释为:

代码语言:javascript
复制
if ( (a == 1) && (b) )

if ( (a == 1) & (b) )

即使变量ab都是整数。这..。

代码语言:javascript
复制
if (a == 1 & b)

..。仍将被称为:

代码语言:javascript
复制
if ( (a == 1) & (b) )

因此,这将在不支持整数/布尔二元性的语言上产生编译错误,例如Java和C#:

代码语言:javascript
复制
if (a == 1 & b)

事实上,在上面的编译错误中,我们甚至可以争辩说,&并没有失去它的逻辑(非短路)操作mojo,我们可以得出结论,Java延续了C语言使&仍然是逻辑操作的传统。因此,我们可以说这是另一种方式,即&可以被重新定位为按位操作(通过应用括号):

代码语言:javascript
复制
if ( a == (1 & b) )

因此,在另一个平行宇宙中,有人可能会问,如何使&表达式成为位掩码操作。

如何编译下面的代码,我在

中读到&是按位操作的。A和b都是整数,但是我不明白为什么下面的按位操作在Java中是一个编译错误:

if (a == 1& b)

或者像这样的问题:

为什么下面的代码没有编译,我在

中读到,当&的两个操作数都是整数时,它是一个按位操作。A和b都是整数,但是我不明白为什么下面的按位操作在Java中是一个编译错误:

if (a == 1& b)

事实上,如果已经存在类似于上面的问题的堆栈溢出问题,我不会感到惊讶,这些问题询问如何在Java中实现屏蔽习惯用法。

为了使语言的逻辑操作解释变得按位,我们必须这样做(在所有语言上,C、Java、C#、PHP等):

代码语言:javascript
复制
if ( a == (1 & b) )

所以要回答这个问题,并不是因为JLS以这种方式定义事物,而是因为Java(以及其他受C语言启发的语言)的&运算符在任何情况下都是逻辑运算符,它保留了C语言的语法和语义。它的方式从C语言开始就是,自古以来就是这样,甚至在我出生之前。

事情不是偶然发生的,JLS 15.22也不是偶然发生的,它有着深厚的历史背景。

在另一个没有引入&&语言的平行世界中,我们仍将使用&进行逻辑操作,今天甚至有人可能会问一个问题:

是真的吗?我们可以使用逻辑运算符&进行按位运算吗?

& 并不关心的操作数是否为整数,是否为布尔值。它仍然是一个逻辑运算符,一个非短路的运算符。事实上,强制它成为位运算符的唯一方法是在Java语言中(甚至在C语言中)用括号将它括起来。即

代码语言:javascript
复制
if ( a == (1 & b) )

想想看,如果&&没有被引入C语言(以及任何抄袭它的语法和语义的语言),现在任何人都可能会问:

如何使用&进行按位操作?

总而言之,首先也是最重要的,Java &本质上是一个逻辑运算符(一个非短路的运算符),它不关心它的操作数,即使两个操作数都是整数(例如,掩码习惯用法),它也会照常进行操作(应用逻辑运算)。您只能通过应用括号将其强制为按位操作。Java延续了C语言的传统

如果Java的&确实是位操作,并且它的操作数(下面示例代码中的整数1和整数变量b )都是整数,则应该编译以下代码:

代码语言:javascript
复制
 int b = 7;
 int a = 1;

 if (a == 1 & b) ...
票数 3
EN

Stack Overflow用户

发布于 2012-07-22 13:45:47

它们(&|)很久以前被用于两个目的,逻辑运算符和按位运算符。如果您了解一下新生的C语言( Java语言就是仿照这种语言),&|就被用作逻辑运算符。

但是,由于在同一语句中消除逐位操作与逻辑操作的歧义非常令人困惑,这促使Dennis Ritchie为逻辑运算符创建了单独的运算符(&&||)。

在此处查看Neonatal 部分:http://cm.bell-labs.com/who/dmr/chist.html

您仍然可以将按位运算符用作逻辑运算符,其保留的运算符优先级就是证明。作为新生C上的逻辑运算符,读出逐位运算符的前世的历史

关于证据,我写了一篇关于比较逻辑运算符和按位运算符的博客文章。如果您尝试在实际程序中进行比较,则不言而喻,所谓的按位运算符仍然是逻辑运算符:http://www.anicehumble.com/2012/05/operator-precedence-101.html

我还在What is the point of the logical operators in C?上回答了一个与您的问题相关的问题

因此,按位运算符也是逻辑运算符,尽管它是短路逻辑运算符的非短路版本。

关于

已经有逻辑运算符&&,||,为什么还要使用&,|,^?

XOR很容易回答,它就像一个单选按钮,只允许一个,下面的代码返回false。为下面的人为代码示例道歉,认为同时喝啤酒和牛奶是不好的信念是debunked already ;-)

代码语言:javascript
复制
String areYouDiabetic = "Yes";
String areYouEatingCarbohydrate = "Yes";


boolean isAllowed = areYouDiabetic == "Yes" ^ areYouEatingCarbohydrate == "Yes";

System.out.println("Allowed: " + isAllowed);

没有等同于XOR位运算符的短路,因为表达式的两边都需要求值。

关于为什么需要使用&|位运算符作为逻辑运算符,坦率地说,您很难找到需要使用位运算符(也称为.非短路逻辑运算符)作为逻辑运算符。逻辑运算可以是非短路的(通过使用按位运算符,也称为非短路逻辑运算符),如果您想要实现一些副作用并使您的代码紧凑(主观),例如:

代码语言:javascript
复制
while ( !password.isValid() & (attempts++ < MAX_ATTEMPTS) ) {

    // re-prompt

}

上面的代码可以重写为以下代码(去掉括号),并且仍然具有与前面代码完全相同的解释。

代码语言:javascript
复制
while ( !password.isValid() & attempts++ < MAX_ATTEMPTS ) {

    // re-prompt

}

去掉括号,但仍然产生与括号相同的解释,可以使逻辑运算符vestige of &更加明显。冒着听起来多余的风险,但我必须强调,未括号的表达式不会被解释为:

代码语言:javascript
复制
while ( ( !password.isValid() & attempts++ ) < MAX_ATTEMPTS ) {

    // re-prompt

}

总而言之,对于非短路逻辑运算,使用&运算符(更普遍地称为按位运算符,但实际上是按位运算和逻辑运算(非短路))来实现副作用是聪明的(主观的),但不被鼓励,它只是一行节省效果,以换取可读性。

示例来源:Reason for the exsistance of non-short-circuit logical operators

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11597978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档