【问题标题】:What does this actually do? - Crazy C++ function这实际上是做什么的? - 疯狂的 C++ 函数
【发布时间】:2011-12-13 15:47:54
【问题描述】:

我正在处理一些遗留代码,并且遇到了一个函数,该函数显然用于在任意长的字段(比 ntohl 可以处理的更大)上执行网络字节顺序转换。

我不能很好地理解它是否除了在 msg 缓冲区范围内颠倒字节顺序之外做任何事情(或者即使它会可靠地做到这一点)。有人可以帮我分解并分析它,以便我可以用更容易理解的东西(或至少评论它)替换它!?

void swapit(unsigned char *msg, int length) {
  for(;length>0;length--, msg++) {
    *msg = ((*msg * 0x0802LU & 0x22110LU) |
            (*msg * 0x8020LU & 0x88440LU)) *
           0x10101LU >> 16;
  }
}

【问题讨论】:

  • 请参阅stackoverflow.com/a/746203/367273,此功能与众多替代方案一起出现。在此基础上投票结束。
  • 这取决于你。它显然值得评论(也许还有其他 SO 问题的链接?:-))
  • 哦,我现在在里面找到了 :) 谢谢老兄。知道写这篇文章的人可能看过了,我感觉好多了,哈哈。
  • 呵呵,请务必使用下一个维护者的链接评论它:)
  • 请注意,反转 bit 顺序(这样做)与反转 byte 顺序不同。将数据从大端系统发送到小端系统不需要位反转。

标签: c++ networking


【解决方案1】:

要了解它是如何工作的,请考虑将操作应用于位模式abcdefgh。 我将用. 表示0 的二进制数,因此非零位会突出显示。

第一个子表达式是:

  ........ ........ abcdefgh
* ........ ....1... ......1. (0x0802)
= .....abc defgh..a bcdefgh.
& ......1. ..1....1 ...1.... (0x22110)
= ......b. ..f....a ...e....

第二个是:

  ........ ........ abcdefgh
* ........ 1....... ..1..... (0x8020)
= .abcdefg h..abcde fgh.....
& ....1... 1....1.. .1...... (0x88440)
= ....d... h....c.. .g......

将它们组合并乘以最终常数得到:

  ......b. ..f....a ...e....
| ....d... h....c.. .g......
= ....d.b. h.f..c.a .g.e....
* .......1 .......1 .......1 (0x10101)
= ....d.b. h.f..c.a .g.e....
 +h.f..c.a .g.e.... ........
 +.g.e.... ........ ........
= hgfedcba hgfe.c.a .g.e....

最后向下移动 16 位得到hgfedcba,与原始模式相反。

【讨论】:

  • 感谢您的详细回答,这使它更容易理解:)
【解决方案2】:

来自这个问题:Best Algorithm for Bit Reversal ( from MSB->LSB to LSB->MSB) in C

它似乎是反转位。

0010 0000 => 0000 0100

【讨论】:

    【解决方案3】:

    在一些小技巧中提到它为Reverse the bits in a byte with 7 operations (no 64-bit)

    【讨论】:

    • +1 参考位旋转黑客!当您使用低级代码时,绝对值得了解。
    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 2017-10-24
    • 2022-09-22
    • 2013-02-04
    • 1970-01-01
    • 2013-03-24
    • 2011-03-11
    • 2010-11-26
    相关资源
    最近更新 更多