您是否曾在实际项目中使用过位移位?

发布于 2024-07-13 10:46:02 字数 152 浏览 5 评论 0原文

您是否曾经在实际的编程项目中使用过位移位? 大多数(如果不是全部)高级语言都包含移位运算符,但是什么时候您实际上需要使用它们?

Have you ever had to use bit shifting in real programming projects? Most (if not all) high level languages have shift operators in them, but when would you actually need to use them?

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

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

发布评论

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

评论(30

人生戏 2024-07-20 10:46:02

我仍然为硬件不支持浮点的系统编写代码。 在这些系统中,几乎所有算术都需要进行位移位。

您还需要轮班来生成哈希值。 多项式算术(CRC、Reed-Solomon 码是主流应用)或也使用移位。

然而,使用轮班只是因为它们很方便并且准确地表达了作者的意图。 如果您愿意,您可以通过乘法来模拟所有位移位,但这会更难编写,可读性较差,有时还会更慢。

编译器会检测乘法可以简化为移位的情况。

I still write code for systems that do not have floating point support in hardware. In these systems you need bit-shifting for nearly all your arithmetic.

Also you need shifts to generate hashes. Polynomial arithmetic (CRC, Reed-Solomon Codes are the mainstream applications) or uses shifts as well.

However, shifts are just used because they are handy and express exactly what the writer intended. You can emulate all bit-shifts with multiplication if you want to, but that would be harder to write, less readable and sometimes slower.

The compilers detect cases where multiplication can be reduced to a shift.

离鸿 2024-07-20 10:46:02

是的,我已经用过它们很多次了。 位旋转对于位掩码非常常见的嵌入式硬件非常重要。 当您需要每一点性能时,这在游戏编程中也很重要。

编辑:此外,我经常使用它们来操作位图,例如更改颜色深度或转换 RGB <-> BGR。

Yes, I've used them a lot of times. Bit twiddling is important on embedded hardware where bit-masks are very common. It's also important in games programming, when you need every last bit of performance.

Edit: Also, I use them a lot for manipulating bitmaps, for example changing the colour depth, or converting RGB <-> BGR.

拒绝两难 2024-07-20 10:46:02
  • 为枚举创建漂亮的标志值(而不是手动键入 1、2、4...)
  • 从位字段中解压数据(许多网络协议都使用它们)
  • Z 曲线遍历
  • 性能黑客

我想不出很多使用它们的案例。 通常是相反的 - 存在一些特定的问题,并且事实证明,采用位运算将产生最佳结果(通常在性能方面 - 时间和/或空间)。

  • Creating nice flag values for the enums (rather than typing manually 1, 2, 4...)
  • Unpacking the data from the bit-fields (many network protocols use them)
  • Z-curve traversal
  • Performance hacks

And I cannot think of many cases when they are being used. It's usually other way around - there is some specific problem, and it turns out that employing bit operations will yield the best results (usually in term of performance - time and/or space).

烟织青萝梦 2024-07-20 10:46:02

我一直使用它们的一个地方是为跨平台应用程序转置整数的字节序。 在位图传输 2D 图形时,它们有时也会派上用场(与其他位操作运算符一起)。

One place I use them all the time is when transposing the endian-ness of integers for cross-platform applications. They also sometimes come in handy (along with other bit-manipulation operators) when blitting 2D graphics.

○闲身 2024-07-20 10:46:02

我已经使用过它们几次,但几乎总是用于解析二进制文件格式。

I've used them a few times, but pretty much always for parsing a binary file format.

临走之时 2024-07-20 10:46:02

位移速度很快。 它们早在除法和模运算出现之前就已经在 CPU 指令集中实现了。 我们中的许多人都使用位移位进行算术,这在铅笔和纸上很简单,但在我们的 CPU 上不可用。

例如:

  • 我在项目中使用了位移位
    涉及大型复合材料的保理
    进入他们的主要因素。
  • 我也使用了位移位
    求平方根和立方根
    任意大的整数。

Bit shifts are fast. They were implemented in CPU instruction sets long before division and modulus operations were. Many of us have used bit shifts for arithmetic that is simple on pencil and paper, but not available on our CPUs.

For example:

  • I've used bit shifts for projects
    involving factoring large composites
    into their prime factors.
  • I have also used bit shifts for
    finding the square and cube root of
    arbitrarily large integers.
_畞蕅 2024-07-20 10:46:02

是的,还是需要的。

例如,在我的工作中,我们开发通过串行端口 COMx 与 PLC 通信的软件。 需要处理一个字节内的位,我们每天都使用左移/右移以及逻辑运算符OR、XOR、AND。

例如,假设我们需要打开字节的第3位(从右到左):

00001001 -> 00001101

这样做更有效率:

Byte B;

B := B OR 4; //100

而不是:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

问候。

Yes, still it's needed.

Here in my job for example we develop softwares for comunication with PLC through the serial port COMx. It's necessary to handle bits within a byte, we use shift left / right, and logic operators OR,XOR,AND in day by day.

For example, let's suppose that we need turn on the bit 3 (right to left) of a byte:

00001001 -> 00001101

It's much more efficient to do:

Byte B;

B := B OR 4; //100

Instead of:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

Regards.

冷…雨湿花 2024-07-20 10:46:02

是的,我有。
正如您可能怀疑的那样,它最有可能在低级编程中找到,例如开发设备的驱动程序。 但是,我参与了一个 C# 项目,我必须开发一个从医疗设备接收数据的 Web 服务。 设备存储的所有二进制数据都被编码到 SOAP 数据包中,但二进制数据被压缩和编码。 因此,要解压缩它,您必须进行大量的位操作。 此外,您还必须进行大量位移才能解析出任何有用的信息,例如设备序列号是第二个字节的下半部分或类似的信息。
我还看到 .NET (C#) 世界中的一些人使用位掩码和标志属性,我个人从来没有这样做的冲动。

Yes, I have.
As you might suspect it's most likely to be found in low level programming, for example developing devices' drivers. But, I worked on a C# project where I had to develop a web service that received data from medical devices. All the binary data that device stored was encoded into SOAP packets, but the binary data was compressed and encoded. So to uncompress it, you would have to do lots and lots of bit manipulations. And furthermore you would have to do lots of bit shifting to parse out any useful information, for example device serial number is a lower half of the second byte or something like that.
Also I've seen some people in .NET (C#) world make a use of Bit masking and Flag Attribute, I personally never had an urge to do it.

情仇皆在手 2024-07-20 10:46:02

当我用汇编语言编写时,我的代码充满了位移位和掩码。

C语言中也有相当多的内容吗?

在 JavaScript 或服务器语言方面还没有做过很多工作。

最好的现代用法可能是逐步遍历表示为 1 和 0 的布尔值的压缩数组。 我过去总是左移并检查汇编中的符号位,但在更高级别的语言中,您需要与值进行比较。

例如,如果有 8 位,则使用“if (a>127) {...}”检查最高位。 然后左移(或乘以 2),与 127 进行“与”(或者如果设置了最后一位,则减去 256),然后再次进行。

When I wrote in assembly language, my code was full of bit-shifting and masking.

Did it a fair amount in C, as well.

Haven't done it much in JavaScript or server languages.

Probably the best modern use is to step through a packed array of boolean values represented as ones and zeros. I used to always left shift and check for sign bit in assembly, but in higher level languages you compare against a value.

For example, if you have 8 bits, you check the top bit with "if (a>127) {...}". Then you left shift (or multiply by 2), do an "and" with 127 (or do a subtraction of 256 if the last bit was set), and do it again.

无人接听 2024-07-20 10:46:02

我在图像压缩/解压缩中经常使用它们,其中位图中的位被压缩。 使用 http://en.wikipedia.org/wiki/Huffman_coding 被压缩的内容包括不同数量的位(它们并不都是字节对齐的),因此在编码或解码时需要对它们进行位移位。

I used them a lot in image compression/decompression, where the bits in a bitmap were compressed. Using http://en.wikipedia.org/wiki/Huffman_coding the things being compressed consist of various numbers of bits (they're not all byte-aligned), and therefore you need to bit-shift them when you encode or decode them.

耳根太软 2024-07-20 10:46:02

例如,在C、C++等语言上的密码方法实现。 二进制文件、压缩算法和逻辑列表操作 - 按位操作总是好的 =)

For example, in cryptographic methods implementation on languages such as C, C++. Binary files, compression algorithms and logical lists operations - bitwise operation is always good =)

酒绊 2024-07-20 10:46:02

位移位并不能解决高级编程问题,只是我们有时必须解决较低级的问题,并且不必用 C 编写单独的库来完成它,这很方便。 我猜那是它使用最多的时候。

我个人曾用它来为 EBCDIC 字符集转换器编写编码器。

Bit shifting doesn't solve high level programming problems, but just we sometimes have to solve lower level problems, and it's convenient to not have to write a separate library in C to do it. That's when it gets used most is my guess.

I have personally used it in writing an encoder for an EBCDIC character set converter.

乜一 2024-07-20 10:46:02

是的。 我之前必须编写加密算法,并且肯定会使用它们。

当使用整数等来跟踪状态时,它们也很有用。

yep. I have to write encryption algorithms before and that definitely uses them.

They are also useful when using integers etc for keeping track of statuses.

浮云落日 2024-07-20 10:46:02

将数字从小端格式转换为大端格式时,反之亦然

When converting numbers from little endian to the big endian format and vice versa

瞄了个咪的 2024-07-20 10:46:02

我在一家计算机外围设备制造商工作。 我几乎每天都遇到过,并且必须实现使用位移位的代码。

I work for a computer peripheral manufacturer. I've encountered, and had to implement code that uses bit shifts, pretty much every day.

寄离 2024-07-20 10:46:02

比特移位在网络游戏协议的破译中被大量使用。 这些协议旨在使用尽可能少的带宽,因此所有信息都被打包到尽可能少的字节中,而不是以 int32 形式传输服务器上的玩家数量、姓名等。 如今,大多数人都使用宽带,这并不是真正必要的,但在最初设计时,人们使用 56k 调制解调器进行游戏,因此每一比特都很重要。

最突出的例子是 Valve 的多人游戏,特别是《反恐精英》和《反恐精英源》。 Quake3 协议也是相同的,但 Unreal 没有那么精简。

这是一个示例 (.NET 1.1)

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

当然,您是否将其视为一个真正的项目或只是一个爱好(在 C# 中)取决于您。

Bit shifting is used a lot in deciphering the protocols of online games. The protocols are designed to use a little bandwidth as possible, so instead of transmitting the number of players on a server, names and so forth in int32s, all the information is packed into as few bytes as possible. It's not really necessary these days with most people using broadband, but when they were originally designed people used 56k modems for gaming, so every bit counted.

The most prominent examples of this are in Valve's multiplayer games particularly Counter-Strike, Counter-Strike Source. The Quake3 protocol is also the same, however Unreal isn't quite as slimline.

Here's an example (.NET 1.1)

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

Of course whether you view this as a real project or just a hobby (in C#) is up to you.

魔法唧唧 2024-07-20 10:46:02

快速傅里叶变换 - FFT 及其 Cooley-Tukey 技术需要使用位移位操作。

Fast Fourier transform — FFT and it's Cooley-Tukey technique will require use bit shifting operations.

余生再见 2024-07-20 10:46:02

查找大于或等于给定数字的最接近的两个幂:在

1 << (int)(ceil(log2(given)))

不支持任意纹理大小的硬件上进行纹理处理时需要。

Find the nearest power of two greater or equal to given number:

1 << (int)(ceil(log2(given)))

Needed for texturing on hardware that does not support arbitrary texture sizes.

英雄似剑 2024-07-20 10:46:02

另一个非常常见的事情是在提取字节的高 半字节 时进行 4 位移位, IE

#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte)  ( (byte)       & 0x0F)

Another very common thing is to do a 4 bit shift when extracting the high nibble of a byte, i.e.

#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte)  ( (byte)       & 0x0F)
来日方长 2024-07-20 10:46:02

是的,在 MPEG2-2 传输流解析器中使用了它们。 它更容易并且更具可读性。

Yes, used them in MPEG2-2 Transport stream parser. It was easier and was better readable.

财迷小姐 2024-07-20 10:46:02

我必须编写一个程序来解析 DVD 光盘上的 .ifo 文件。 这些字段解释了光盘上有多少标题、章节、菜单等。 它们由各种大小和对齐方式的打包位组成。 我怀疑许多二进制格式都需要类似的位移位。

I had to write a program to parse the .ifo files on DVD discs. These are the fileds that explain how many titles, chapters, menus, etc. are on the disc. They are made up of packed bits of all sizes and alignments. I suspect many binary formats require similar bit shifting.

黄昏下泛黄的笔记 2024-07-20 10:46:02

我见过当多个标志用作属性参数时使​​用的按位运算符。 例如,数字 4 = 1 0 0 表示设置了三个标志之一。 这对于公共 API 来说并不好,但它可以在特殊情况下加快速度,因为检查位的速度很快。

I have seen bitwise operators used when multiple flags were used as a property parameter. For example number 4 = 1 0 0 means that one of the three flags is set. This is not good for public API but it can speed up things in special cases since checking for bits is fast.

九歌凝 2024-07-20 10:46:02

我写过的每一个 bitblt-er 都无法在没有左右滑动位的能力的情况下完成。

Every bitblt-er i ever wrote couldn't have been completed w/o ability to slide bits left and right.

救星 2024-07-20 10:46:02

我在游戏中使用它们将一堆标志打包到单个字节/字符中,以便保存到数据卡中。 诸如存储可解锁状态等之类的事情。现在虽然要求不高,但可以节省工作量。

I've used them on games for packing a bunch of flags into a single byte / char for saving out to a data card. Things like storing the status of unlockables etc. Not so much of a requirement nowadays, but can save work.

踏月而来 2024-07-20 10:46:02

我在一个嵌入式系统项目中使用它,该系统必须读取显示器的 EDID 数据。
EDID 中的某些数据的编码如下:

字节 #3:
水平消隐——低 8 位
字节#4:
低半字节:水平消隐——高 4 位
上半边:其他的东西

I use it in a project for an embedded system that has to read a monitor's EDID data.
Some data in an EDID is encoded like this:

Byte #3:
Horizontal Blanking -- lower 8 bits
Byte #4:
Lower Nibble: Horizontal Blanking -- upper 4 bits
Upper Nibble: something else

天气好吗我好吗 2024-07-20 10:46:02

是的,在Java和C#应用程序之间进行二进制通信时,一种是big-endian字节顺序,另一种是little-endian(不一定按照这个顺序)。 我创建了一个 InputStream 类,它可以读取具有不同字节顺序的数字,并且它使用字节移位来工作。

有时,当您想将 4 个短整型放入长整型的 4 个字节中时,也会使用字节移位。 我想我很多年前就这么做过...

Yes, when performing binary communication between Java and C# applications, one is big-endian byte ordering and the other is little-endian (not necessarily on this order). I created an InputStream class that could read numbers with a different byte order, and it used byte-shifting in order to work.

Sometimes also when you want to put 4 shorts in the 4 bytes of a long, it would be case the of using byte shifting. I think I did that many years ago...

泪意 2024-07-20 10:46:02

与“较低级别”设备(例如数字以太网 IO 盒或 PLC)通信时也需要位移位,这些设备通常将单独的输入/输出值打包为字节。

Bit shifting is also required when communicating with "lower level" equiment, eq digital ethernet-IO -boxes or PLC's, which usually pack invidual input/output values into bytes.

残疾 2024-07-20 10:46:02

是的,位移位一直在低级嵌入式软件中使用。 它还可以用作执行极快数学运算的近乎魔术,请查看

http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/

Yes, bit shifting is being used at low-level embedded software all the time. It can also be used as an almost magic trick to perform extremely fast math operations, have a look at

http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/

梦开始←不甜 2024-07-20 10:46:02

是的,一直如此。 就像这些用于将 3space 坐标打包到 32 位整数或从 32 位整数解包的宏一样:

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        

Yes, all the time. Like these macros for packing and unpacking a 3space coordinate to/from a 32-bit integer:

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        
浅笑轻吟梦一曲 2024-07-20 10:46:02

我曾经(很多很多年前)为一个使用 Excel Oper 结构创建 Excel 电子表格的项目编写了一个输出例程。 这是一个二进制文件共振峰,需要大量的位调整。 以下链接介绍了 Oper 结构 Safari Books

I once (many, many years ago) wrote an output routine for a project which created Excel Spreadsheets using the Excel Oper structure. This was a binary file formant which required a large amount of bit twiddling. The following link gives a flavour of the Oper structure Safari Books.

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