除了快速数学之外,还有什么充分的理由使用位移位吗?

发布于 2024-09-18 09:02:37 字数 114 浏览 6 评论 0原文

我了解按位运算以及它们如何用于不同的目的,例如权限。但是,我似乎不明白位移运算符有什么用。我理解它们是如何工作的,但我想不出任何可能想要使用它们的场景,除非我想做一些非常快速的乘法或除法。使用位移位还有其他原因吗?

I understand bitwise operations and how they might be useful for different purposes, e.g. permissions. However, I don't seem to understand what use the bit shift operators are. I understand how they work, but I can't think of any scenarios where I might want to use them unless I want to do some really quick multiplication or division. Are there any other reasons to use bit-shifting?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忘你却要生生世世 2024-09-25 09:02:37

原因有很多,以下是一些:

  1. 假设您将黑白图像表示为位序列,并且您希望在该图像中设置单个像素。例如,您的字节偏移量可能是 x>>3,而您的位偏移量可能是 x >3。 0x7,您可以通过以下方式设置该位:byte = byte | (1 << (x & 0x7));
  2. 实现处理可变长度位序列的数据压缩算法,例如霍夫曼编码。
  3. 您正在与某些硬件(例如串行通信设备)进行交互,并且需要读取或设置一些控制位。

由于这些和其他原因,大多数处理器都具有位移和/或旋转指令以及其他逻辑指令(和/或/异或/非)。

从历史上看,乘法和除法的速度要慢得多,因为它们是更复杂的运算,而有些 CPU 根本没有这些运算。

另请参阅此处:
您是否曾经在实际中使用过位移位项目?

There are many reasons, here are some:

  1. Let's say you represent a black and white image as a sequence of bits and you want to set a single pixel in this image generically. For example your byte offset may be x>>3 and your bit offset may be x & 0x7 and you can set that bit by: byte = byte | (1 << (x & 0x7));
  2. Implementing data compression algorithms where you deal with variable length bit sequences, e.g. huffman coding.
  3. You're are interacting with some hardware, e.g. a serial communication device, and you need to read or set some control bits.

For those and other reasons most processors have bit shift and/or rotation instructions as well as other logic instructions (and/or/xor/not).

Historically multiplication and division were significantly slower as they are more complex operations and some CPUs didn't have those at all.

Also see here:
Have you ever had to use bit shifting in real projects?

余生一个溪 2024-09-25 09:02:37

正如您所指出的,左移与乘以二是一样的。至少当我们谈论无符号数量时是这样。有符号量“左移”的含义……取决于语言。

对于现代编译器,编写“i = x*2;”实际上没有区别。且“i = x << 1;”编译器将生成最有效的代码。所以从这个意义上说,没有理由更喜欢移位而不是乘法。

一些算法的工作原理是将数量左移一位,然后将低位设置为 0 或 1。一些简单的压缩算法就是这样工作的。例如,如果您的累计值在变量 x 中,当前值(0 或 1)在 y 中,那么编写“x = (x << 1) | y”更有意义,而不是“x = (x * 2) + y”。两者都做同样的事情,但第一个在符号上更正确。您不必想:“哦,对了,乘以二与左移相同。”

另外,当您谈论移位位的算法时,向左或向右移动特定位数比计算要乘或除的 2 的倍数更方便。

因此,虽然移位而不是乘法通常不会带来性能优势(至少在使用高级语言时不会),但有时,具有移位能力会使您所做的事情更容易理解。

As you indicate, a left shift is the same thing as a multiplication by two. At least it is when we're talking about unsigned quantities. The meaning of a "left shift" of a signed quantity is ... language dependent.

With modern compilers, there's really no difference between writing "i = x*2;" and "i = x << 1;" The compiler will generate the most efficient code. So in that sense there's no reason to prefer shift over multiply.

Some algorithms work by shifting a quantity left by one bit and then setting the low bit to either 0 or 1. Some simple compression algorithms work this way. For example, if your accumulated value is in the variable x, and the current value (0 or 1) is in y, then it makes more sense to write "x = (x << 1) | y", rather than "x = (x * 2) + y". Both do the same thing, but the first is more notationally correct. You don't have to think, "oh, right, multiply by two is the same as a left shift."

Also, when you're talking about algorithms that shift bits, it's more convenient to shift left or right by a particular number of bits than to figure out what multiple of 2 you want to multiply or divide by.

So, whereas there's typically no performance benefit to shifting rather than multiplying--at least not when working with high level languages--there are times when having the ability to shift makes what you're doing more easily understood.

注定孤独终老 2024-09-25 09:02:37

除了数值计算之外,还有很多地方经常使用移位运算。例如,Bitboard 是棋盘游戏中常用的棋盘表示数据结构。一些最强大的国际象棋引擎使用这种数据结构主要是为了速度和轻松地移动生成和评估。这些程序大量使用位运算,并且位移位运算专门用于许多上下文中 - 例如查找位掩码、在棋盘上生成新的移动、快速计算对数等。甚至可以进行非常高级的数值计算通过巧妙地使用位运算来优雅地完成。查看此网站了解位旋转黑客 - 很多算法都使用移位运算符。移位操作经常用于设备驱动程序编程、编解码器开发、嵌入式系统编程等。

There are lot of places where bit shift operations are regularly used outside of their usage in numerical computations. For example, Bitboard is a data structure that is commonly used in board games for board representation. Some of the strongest chess engines use this data structure mainly for speed and ease of move generation and evaluation. These programs use bit operations heavily and bit-shift operations specifically are used in a lot of contexts - such as finding bit masks, generating new moves on the board, computing logarithm very quickly, etc. There are even very advanced numerical computations that can be done elegantly by clever use of bit operations. Check out this site for bit twiddling hacks - a lot of those algorithms use shift operators. Bit shift operations are regularly used in device driver programming, codec development, embedded systems programming and so on.

烟沫凡尘 2024-09-25 09:02:37

移位允许访问变量内的特定位。表达式 (n >> p) & ((1 << m) - 1) 检索变量 nm 位部分,偏移量为 p代码> 从右侧开始位。

这允许您的程序使用不是 8 位倍数的整数,这对于数据压缩很有用。

例如,我在我的 Netflix 奖品 程序中使用它来打包记录(22 位用户 ID + 15-位电影 ID + 12 位日期 + 3 位评级)转换为 uint64_t (还有 12 位备用)。

一个非常常见的特殊情况是将 8 个 bool 变量打包到每个字节中。 (Unix 文件权限、黑白位图、CPU 标志寄存器等)

此外,UTF-8,这是一种非常流行的字符编码。 Unicode 字符通过将其位分布在 1、2、3 或 4 个字节中来表示。

Shifting allows accessing specific bits within a variable. The expression (n >> p) & ((1 << m) - 1) retrieves an m-bit portion of the variable n with an offset of p bits from the right.

This allows your program to use integers that aren't multiples of 8 bits, which is useful for data compression.

For example, I used it in my Netflix Prize programs to pack records (22-bit user ID + 15-bit movie ID + 12-bit date + 3-bit rating) into a uint64_t (with 12 bits to spare).

A very common special case is to pack 8 bool variables into each byte. (Unix file permissions, black-and-white bitmaps, CPU flags registers, etc.)

Also, bit manipulation is used in UTF-8, which is a very popular character encoding. Unicode characters are represented by distributing their bits across 1, 2, 3, or 4 bytes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文