42

虽然我掌握了位运算符的概念,但我不能说我在 Web 开发过程中遇到了许多不得不求助于位运算符的用例。

  • 您使用按位运算符吗?
  • 你为什么使用它们?
  • 有哪些示例用例?

请记住,此问题专门用于在 Web 语言中使用位运算符。

4

10 回答 10

86

我将在这里更加明确,因为我认为按位掩码是一个很棒的工具,应该在任何开发人员带中。我将尝试扩展上面的答案。首先,一个使用整数来维护状态标志的例子(常见用法):

// These are my masks
private static final int MASK_DID_HOMEWORK  = 0x0001;
private static final int MASK_ATE_DINNER    = 0x0002;
private static final int MASK_SLEPT_WELL    = 0x0004; 

// This is my current state
private int m_nCurState;

为了设置我的状态,我使用按位 OR 运算符:

// Set state for'ate dinner' and 'slept well' to 'on'
m_nCurState = m_nCurState | (MASK_ATE_DINNER | MASK_SLEPT_WELL);

请注意我如何“或”我当前的状态与我想要“打开”的状态。谁知道我现在的状态是什么,我不想把它吹走。

取消设置我的状态,我将按位 AND 运算符与补码运算符一起使用:

// Turn off the 'ate dinner' flag
m_nCurState = (m_nCurState & ~MASK_ATE_DINNER);

检查我当前的状态,我使用 AND 运算符:

// Check if I did my homework
if (0 != (m_nCurState & MASK_DID_HOMEWORK)) {
    // yep
} else { 
    // nope...
}

为什么我觉得这很有趣?假设我正在设计一个设置我的状态的界面。我可以编写一个接受三个布尔值的方法:

void setState( boolean bDidHomework, boolean bAteDinner, boolean bSleptWell);

或者,我可以使用一个数字来表示所有三种状态并传递一个值:

void setState( int nStateBits);

如果您选择第二种模式,当您决定添加另一个状态时会非常高兴——您不必破坏界面的现有实现。

我的两分钱。谢谢。

于 2008-11-04T08:16:36.210 回答
53

我对位运算符的主要用途可能与任何地方相关——代表一组标志。例如,您可能在数据库中有一个整数,表示用户的一组安全权限,而在您的 Web 应用程序中,您必须在继续之前检查这些权限。

那些往往只需要&|- 例如

if ((permissions & Permission.CreateUser) != 0)
{
    ...
}

或者

Permission requiredPermission = Permission.CreateUser
                                | Permission.ChangePassword;

根据我的经验,位移运算符在“商业”应用程序中的用处不大。

于 2008-11-04T06:31:27.670 回答
13

对于 Java 程序员,异或位运算符 (^) 提供了一种有用的方法来编写两个布尔值之间的异或测试。例子:

boolean isFoo = ...
boolean isBar = ...

if (isFoo ^ isBar) {
    // Either isFoo is true or isBar is true, but not both.

注意:这里没有实际的位操作,但它是使用 xor 位运算符(在 Web 层或其他任何地方)的有用方法。

(这可能适用于 C#,因为它与 Java 非常相似。但不确定。)

于 2008-11-04T13:42:03.823 回答
6

除了标志之外,没有太多理由在脚本语言中使用位操作。但是,一旦您深入研究堆栈的较低级别,位操作就变得越来越重要。

于 2008-11-04T06:47:00.153 回答
6

这个问题已经回答了,但我想分享我的经验&

不久前,当我进行 ASP.NET C# 练习时,我曾使用&过验证注册表单,在该练习中,短路&&不会轻易达到预期的效果。

我想要做的是突出显示表单中的所有无效字段并在每个无效字段旁边显示错误消息标签,并取消突出显示所有有效字段并从中删除错误消息。

我使用的代码是这样的:

protected void btnSubmitClicked(...) {
  username = txtUsername.Text;
  email = txtEmail.Text;
  pass = txtPassword.Text;
  if (isUsernameValid(username) & isEmailValid(email) & isPasswordValid(pass)) {
    // form is valid
  } else {
    // form is invalid
  }
  ...
}

private bool isPasswordValid(string password) {
  bool valid = true;
  string msg = "";
  if (password.length < MIN_PASSWORD_SIZE) {
    valid = false;
    msg = "Password must be at least " + MIN_PASSWORD_SIZE + " long.";
  }

  highlightField(txtPassword, lblPassword, valid, msg);
  return valid;
}

private void highlightField(WebControl field, Label label, string valid, string msg) {
  if (isValid) {
    // de-highlight
    field.BorderColor = VALID_FIELD_COLOR;
  } else {
    // highlight the text field and focus on it
    field.BorderColor = INVALID_FIELD_COLOR;
    field.Focus();
  }

  label.Text = msg;
}

// and other similar functions for username and email

如果我使用&&而不是&,方法中的 if 语句btnSubmitClicked将仅突出显示第一个无效字段,之后的所有其他无效字段将不会突出显示,并且其错误消息不会显示,因为短路&&后会停止检查条件遇到错误。

可能有更好的方法来实现相同的目标,但我&当时发现很有用。

于 2013-11-14T02:30:56.940 回答
2

通常,您不需要关心位级别的操作。您可以考虑字节、整数、双精度和其他更高级别的数据类型。但是有时您希望能够达到单个位的水平。

位运算符最常见的使用案例之一是标志(php 示例)。位运算符也用于二进制文件 IO 操作。

于 2008-11-04T06:35:05.247 回答
1

我经常使用它们,但从不在我可以避免它们的地方使用。我最常使用它们的是以下两种情况。

  1. 在不通过安全连接的情况下使用 JavaScript 加密来自客户端的表单数据,它比发送纯文本要好得多。
  2. 动态生成的来自 PHP 的流式文件结构(通常是一些二进制文件类型)。
于 2008-11-04T06:32:40.710 回答
1

在题外话方面,在高级语言中,尤其是在解析语言(如 PHP)中,按位运算比普通算术要慢很多[需要引用] 。因此,虽然从性能的角度来看 Jon 的权限检查可能没问题,但它在 Web 域中并不是很“原生”。

于 2008-11-04T06:43:23.887 回答
0

我唯一一次在授权访问之外使用它们是我为解析器所做的一个项目,该解析器将颜色 ID 分配给整数

IE

$color_red= 1;
$color_blue = 2;
$color_yellow = 8;

$color_purple = 3;
$color_orange = 9;
$color_green  = 10;

然后我得到了一个财产

$can_collect_200_dollars = 10;

然后使用按位比较给定的颜色与属性

if($given_color & $can_collect_200_dollars)
{
    $yay_i_got_200_dollars = true;
}else{
    $bummer_i_am_going_to_jail = true;
}
于 2009-03-17T20:09:14.987 回答
-2

我认为如果使用得当,按位运算符非常强大。

假设您有一个“在线商店”。而且您的某些商品属于不止一个类别。

要么你必须创建一个多对多关系。或者您可以为您的类别提供一个额外的二进制 ID,然后在您的产品中存储类别 ID 的按位组合

我想在几行中我无法详细解释。对不起

于 2009-11-11T16:56:08.823 回答