你有没有在实际项目中使用位移?
你有没有在真正的编程项目中使用位移 ? 大多数(如果不是全部的话)高级语言都有移位操作符,但是什么时候才需要使用它们呢?
我仍然为硬件中没有浮点支持的系统编写代码。 在这些系统中,几乎所有的算术都需要进行位移。
你也需要转移生成哈希值。 多项式algorithm(CRC,里德 – 所罗门码是主stream应用)或使用移位。
然而,换class只是因为他们很方便,而且正好expression了作者的意图。 如果你愿意的话,你可以用乘法来模拟所有的比特位移,但是这样写起来会比较困难,可读性差一些,有时候会比较慢。
编译器检测乘法可以减less到一个class次的情况。
是的,我用了很多次。 在位掩码非常普遍的embedded式硬件中,位旋转是非常重要的。 在游戏编程中,当你需要最后一点的performance时,这也是非常重要的。
编辑:另外,我用它们处理位图很多,例如改变颜色深度,或者转换RGB < – > BGR。
- 为枚举创build漂亮的标志值(而不是手动input1,2,4 …)
- 将数据从位域中解包(许多networking协议使用它们)
- Z曲线遍历
- 性能骇客
在使用的时候,我想不到很多情况。 通常情况下,这是一个特殊的问题,事实certificate,使用位操作会产生最好的结果(通常是性能 – 时间和/或空间)。
我一直使用它们的一个地方是将整数的序列转置为跨平台的应用程序。 它们有时也会派上用场(与其他位操作操作符一起),当传输2Dgraphics时。
我已经使用了它们几次,但几乎总是用于parsing二进制文件格式。
合理的文章在这里: http : //greatjustice.info/the-lost-art-of-bitmasks/
位移很快。 早在分割和模数运算之前,它们都是在CPU指令集中实现的。 我们中的许多人使用位移来进行算术运算,这在铅笔和纸张上很简单,但在我们的CPU上却不可用。
例如:
- 我已经使用了将大型复合材料分解为主要因素的项目。
- 我也用位移来find任意大整数的平方和立方根。
是的,仍然需要。
在我的工作中,例如我们通过串口COMx开发与PLC通信的软件。 有必要处理一个字节内的位,我们使用左移/右移和逻辑运算符OR,XOR,AND在日复一日。
例如,假设我们需要打开一个字节的第3位(从右到左):
这样做更有效率:
Byte B; B := B XOR 4;
代替:
Byte B = 0; String s; // 0 based index s = ConvertToBinary (B); s[5] = "1"; B := ConvertToDecimal (s);
问候。
位移并不能解决高层次的编程问题,但是我们有时需要解决低层次的问题,而且不必在C中编写单独的库来实现它。 那是什么时候它被使用最多的是我的猜测。
我亲自用它来编写EBCDIC字符集转换器的编码器。
将数字从小端转换为大端时,反之亦然
当我用汇编语言编写代码时,我的代码充满了位移和掩盖。
C也有相当的数量。
在JavaScript或服务器语言中没有做太多的事情。
可能最好的现代使用是逐步通过一个布尔值的数组表示为1和零。 我以前总是左移,检查程序集中的符号位,但在更高级的语言中,您可以比较一个值。
例如,如果你有8位,你用“if(a> 127){…}”来检查最高位。 然后你左移(或乘以2),用127(或者如果最后一位被设置,减去256)做一个“和”,然后再做一次。
我在图像压缩/解压缩中使用了很多,位图中的位被压缩。 使用http://en.wikipedia.org/wiki/Huffman_coding ,被压缩的东西由不同数量的比特组成(它们不是全部是字节alignment的),因此当你对它们进行编码或解码时,你需要对它们进行位移。
例如,在诸如C,C ++等语言的encryption方法实现中。 二进制文件,压缩algorithm和逻辑列表操作 – 按位操作总是很好=)
是的,我有。 正如您可能会怀疑它最可能在低级编程中发现的,例如开发设备的驱动程序。 但是,我从事的是一个C#项目,我不得不开发一个从医疗设备接收数据的Web服务。 设备存储的所有二进制数据都被编码为SOAP数据包,但二进制数据被压缩和编码。 所以要解压它,你必须做很多很多的操作。 此外,你将不得不做大量的位移来parsing出任何有用的信息,例如设备序列号是第二个字节的下半部分或类似的东西。 我也见过.NET(C#)世界中的一些人使用位掩码和标记属性,我个人从来没有这样做的冲动。
是的。 我必须在之前编写encryptionalgorithm,而且肯定会使用它们。
当使用整数等来跟踪状态时,它们也是有用的。
我为一个电脑外设制造商工作。 我遇到过,并且不得不实现使用位移的代码,几乎每天都这样。
找出两个大于或等于给定数字的最近幂:
1 << (int)(ceil(log2(given)))
需要在不支持任意纹理大小的硬件上进行纹理化。
快速傅立叶变换–FFT和它的Cooley-Tukey技术将需要使用位移位操作。
我已经看到当多个标志被用作属性参数时使用了按位运算符。 例如,数字4 = 1 0 0表示三个标志之一被设置。 这对于公共API来说并不好,但是由于检查比特速度很快,所以它可以在特殊情况下加快速度。
是的,在Java和C#应用程序之间执行二进制通信时,一个是big-endian字节sorting,另一个是little-endian(不一定按照此顺序)。 我创build了一个InputStream类,它可以读取不同字节顺序的数字,并使用字节移位来工作。
有时候,当你想在一个长的4个字节中放4个短路时,这将是使用字节移位的情况。 我想我是那么多年以前做的…
位移在解密在线游戏的协议中使用很多。 这些协议被devise为尽可能使用一些带宽,所以所有的信息都被打包成尽可能less的字节,而不是传输服务器上的播放器数量,名字等等。 现在大多数人使用宽带并不是真的需要,但是当他们最初devise的时候,人们使用56k调制解调器来进行游戏,所以每一位都被计算在内。
其中最突出的例子就是Valve的多人游戏,特别是“反恐精英”(Counter-Strike),“反恐精英”(Counter-Strike Source)。 Quake3协议也是一样的,但是虚幻并不是很苗条。
这里是一个例子(.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#中)取决于你。
另一个非常常见的事情是在提取一个字节的高四位时做4位移位,
#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F) #define LOW_NIBBLE(byte) ( (byte) & 0x0F)
是的,在MPEG2-2传输streamparsing器中使用它们。 这是更容易,更好的可读性。
我必须编写一个程序来parsingDVD光盘上的.ifo文件。 这些文件解释了光盘上有多less标题,章节,菜单等。 他们是由各种尺寸和路线的打包位组成的。 我怀疑许多二进制格式需要类似的位移。
我写的每一个字节都不能完成,不能左右滑动位。
我已经在游戏中使用它们将一堆标志打包成一个字节/字符,用于存储数据卡。 像存储解锁的状态等东西现在没有这么多的要求,但可以节省工作。
我在一个需要读取显示器的EDID数据的embedded式系统的项目中使用它。 EDID中的一些数据是这样编码的:
字节#3:
水平消隐 – 低8位
字节#4:
低半字节:水平消隐 – 高4位
上半身:别的东西
与“低级”设备,eq数字以太网IO盒或PLC通信时,也需要位移,通常将各个input/输出值打包为字节。
是的,一直在低级embedded式软件中使用移位。 它也可以作为一个几乎魔术技巧来执行极其快速的math运算,看看
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
是的,所有的时间。 就像这些macros一样,用于打包和解压32位整数的3位空间坐标:
#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))