Ruby 运算符之按位运算符 ( bitwise )

yufei       6 年, 3 月 前       1662

无聊翻了下 Medium 中 Ruby 的相关的内容,发现有一篇文章介绍 Ruby 中的按位运算符 bitwise 非常简单,因此翻译在此。

按位运算符并没有把所有的数字 ( Numbers ) 看成是整型 ( integer ),而是把它们看成是一个位 ( bit ) 序列。

这是一个非常有用的概念,因为它把 「 掩码 」的概念带入 「 整型 」( integer ) 中。例如验证 MCQ 的答案是否正确这样。

本文接下来的部分,我们就来了解下 Ruby 中的这个 bitwise 运算符。

十进制转二进制

十进制 应该没啥好解释了吧,我们日常中使用的都是十进制。十进制有十个值,分别是 0123456789

也许你也听说过二进制,也知道它是计算机进行操作的基础。二进制只有两个值 01

二进制中,每个位 ( bit ) 的权重是 2 的倍数。每个值从右到左分配。

  • 第一个位 ( 从右往左 ) 的值为 1
  • 第二个位的值为 2
  • 第三个位的值位 4
  • ...以此类推

如果某个位 ( n ) 的值为 1 ,则总和的结果需要加上 2n-1 次方的值

我们来看一个范例,了解如何转换二进制的值。在这个范例中,我们将十进制 34 转换为二进制

128 64 32 16  8 4 2 1
 |   |  |  |  | | | |
 0   0  1  0  0 0 1 0

因此,需要将十进制 34 转换为二进制,我们可以从左向右移动,并应用以下规则

  1. 128 包含在 34 中吗 ? 没有,因此该位的值为 0
  2. 64 包含在 34 中吗 ? 没有,因此该位的值为 0
  3. 32 包含在 34 中吗 ? 有, 34-32 = 2 ,因此该位为 1 ,然后使用 2 继续向下运算
  4. 16 包含在 2 中吗 ? 没有,因此该位的值为 0
  5. 8 包含在 2 中吗 ? 没有,因此该位的值为 0
  6. 4 包含在 2 中吗 ? 没有,因此该位的值为 0
  7. 2 包含在 2 中吗 ? 有,2-2=0 ,因此该位的值为 0 ,然后使用剩余的值 0 继续向下运算
  8. 1 包含在 0 中吗 ? 没有,因此该位的值为 0

综上所述,只有 32 和 2 设置为 1

二进制

正如我们在介绍中看到的那样,按位运算符将整数视为位序列 - 基于二进制 ( base 2 ) 而不是基于十进制 ( base 10 )。

那么,问题来了,如何将整数看成是位序列呢 ?

$> 4.to_s(2)
 => "100"

Integer#to_s(base = 10) 将一个十进制整数转换为其它进制的数字,参数 base 用于指定要转换到的进制,默认是十进制,如果传递 base=2 ,则就是要把整数转换为二进制。

to_s(2) 并不会返回二进制中前面的 0 。它返回一个字符串,包含了以从左到右遇到的第一个 1 个开头的位序列

按位与 「 AND 」 & 操作符

按位与运算其实就是对于位序列中的每个位进行 & 运算。

为了方便你理解这个 & 运算符,我们来演示下如何计算 7 & 5

7 的二进制: 0000 0111
5 的二进制: 0000 0101

  128 64 32 16 8 4 2 1
 ---------------------- 
7: 0  0  0  0  0 1 1 1
   &  &  &  &  & & & &
5: 0  0  0  0  0 1 0 1
-----------------------
5: 0  0  0  0  0 1 0 1

因此,7 & 5 的运算结果为 5

如果我们使用 Ruby 中的 & 运算符,结算结果如下

$> 7 & 5
 => 5
$> (7 & 5).to_s(2)
 => "101"

按位或 「 OR 」 | 运算符

按位或运算其实就是对于位序列中的每个位进行 | 运算。

为了方便理解这个 | 运算符,我们来演示下如何计算 7 | 5

7 的二进制: 0000 0111
5 的二进制: 0000 0101
  128 64 32 16 8 4 2 1
 ---------------------- 
7: 0  0  0  0  0 1 1 1
   |  |  |  |  | | | |
5: 0  0  0  0  0 1 0 1
 ----------------------
7: 0  0  0  0  0 1 1 1

因此,7 | 5 的运算结果为 7

如果我们使用 Ruby 中的 | 运算符,结算结果如下

$> 7 | 5
 => 7
$> (7 | 5).to_s(2)
 => "111"

左移 「 LEFT SHIFT 」 运算符

左移运算符 ( LEFT SHIFT ) << 将数字的每个位向左移位 n 个位置,右边的空位补 0

为了方便理解这个 << 运算符,我们来演示下如何计算 7 << 2

7 的二进制: 0000 0111
   128 64 32 16  8 4 2 1
   ---------------------- 
7:  0  0  0  0   0 1 1 1
将每个位左移 2 个位置
   ----------------------
28: 0  0  0  1   1 1 0 0

因此,7 << 2 的运算结果为 28

如果我们使用 Ruby 中的 << 运算符,结算结果如下

$> 7 << 2
 => 28
$> (7 << 2).to_s(2)
 => "11100"

右移 「 RIGHT SHIFT 」 运算符

左移运算符 ( RIGHT SHIFT ) >> 将数字的每个位向右移位 n 个位置,左边的空位补 0

为了方便理解这个 >> 运算符,我们来演示下如何计算 40 >> 2

40 的二进制: 0010 1000
   128 64 32 16  8 4 2 1
   ---------------------- 
7:  0  0  1  0   1 0 0 0
将每个位右移 2 个位置
   ----------------------
10: 0  0  0  0   1 0 1 0

因此,40 >> 2 的运算结果为 10

如果我们使用 Ruby 中的 >> 运算符,结算结果如下

$> 40 >> 2
 => 10
$> (40 >> 2).to_s(2)
 => "1010"

结束语

按位运算符在 Rails 中并不常用,但当我们需要 MCQ 测试,配置,选项等 「 多选项 」 功能时可以非常方便。

请注意,本文中并没有介绍其它 2 个按位运算符:「按位异或」和 「 按位非 」运算符。我可能会在另一篇文章中介绍它们

源文连接地址为 https://medium.com/@farsi_mehdi/ruby-bitwise-operators-da57763fa368

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.