【问题标题】:Getting 32 bit words out of 64-bit values in C/C++ and not worrying about endianness在 C/C++ 中从 64 位值中获取 32 位字,而不用担心字节顺序
【发布时间】:2023-03-30 00:39:01
【问题描述】:

据我了解,在 C/C++ 中,位运算符应该是独立于字节序的,并且按照您期望的方式运行。我想确保我真正从 64 位值中得到最重要和最不重要的单词,而不用担心机器的字节顺序。这是一个例子:

uint64_t temp;
uint32_t msw, lsw;
msw = (temp & 0xFFFFFFFF00000000) >> 32;
lsw = temp & 0x00000000FFFFFFFF;

这行得通吗?

【问题讨论】:

标签: c++ c bit-manipulation endianness bitwise-operators


【解决方案1】:

是的。 它应该可以工作。

【讨论】:

    【解决方案2】:

    6.5.7 移位运算符

    4 E1

    所以,是的——由标准保证。

    【讨论】:

      【解决方案3】:

      我认为你说的很对,但这对你有什么影响?

      如果你有一些字面值,那么你就知道哪一端是哪一端。但是,如果您发现自己的值来自程序外部,那么您就无法确定,除非它们以某种方式进行了编码。

      【讨论】:

        【解决方案4】:

        是的,应该可以。当您检索 msw 时,您的掩码并没有真正完成太多 - 无论如何,当您进行移位时,您掩码为零的位将被丢弃。就个人而言,我可能会使用这样的东西:

        uint32_t lsw = -1, msw = -1;
        lsw &= temp;
        msw &= temp >> 32;
        

        当然,要产生有意义的结果,temp 必须被初始化,它不在您的代码中。

        【讨论】:

        • 是的,在这种情况下,我并不关心 temp 的值,只是对我实际上得到了 msw 和 lsw 的健全性检查。
        • &= 在这里做了哪些普通作业不会做的事情?
        • @Rob:只要目标正好是所需的输出大小,它就不会完成任何事情。但是,如果您想要像底部 24 位这样的东西,并且必须将其放入 32 位类型,那么您需要屏蔽它。
        【解决方案5】:

        我想分享一个想法,也许你可以通过使用<arpa/inet.h>中的函数或宏来绕过值的字节顺序,将网络转换为主机顺序,反之亦然,可以说它更多地与套接字一起使用,但它可以用于此实例以保证来自另一个处理器的 0xABCD 之类的值在 Intel x86 上仍然是 0xABCD,而不是诉诸手工编码的自定义函数来处理字节序建筑....?!

        编辑:这是CodeProject 上关于 Endianess 的文章,作者开发了宏来处理 64 位值。

        希望这会有所帮助, 最好的祝福, 汤姆。

        【讨论】:

        • 在我看来,海报并不关心字节序,而是将 64 位转换为最高有效和最低有效 32。大概 32 位整数将具有与 64 位相同的字节序整数。
        【解决方案6】:

        除了其他响应之外,我还要补充一点,您不应该担心 C 中的字节顺序。字节顺序问题仅来自于查看与最初用于写入这些字节的类型不同的某些字节。当你这样做时,你很可能会遇到别名问题,这意味着你的代码在使用另一个编译器或另一个优化标志时可能会中断。

        只要您不尝试进行此类跨类型访问,您的代码就应该是端中立的,并且可以在小端和大端架构上完美运行。或者,换句话说,如果你有字节序问题,那么其他更大的麻烦也潜伏在附近。

        【讨论】:

          【解决方案7】:

          它会起作用,但是一些作者在位移位之前进行位掩码的奇怪倾向总是让我感到困惑。

          在我看来,一种更优雅的方法是首先进行转变的方法

          msw = (temp >> 32) & 0xFFFFFFFF; 
          lsw = temp & 0xFFFFFFFF; 
          

          至少因为它每次都使用相同的“神奇”位掩码常量。

          现在,如果您的目标类型是无符号的并且已经具有所需的位宽,则完全不需要屏蔽

          msw = temp >> 32; 
          lsw = temp; 
          

          【讨论】:

          • 哇,我很高兴至少有人提到这样做! +1 以保持位掩码的一致性 :)
          【解决方案8】:

          字节顺序与内存布局有关。移位是关于位(和位布局)。字的意义是关于位布局,而不是内存布局。所以字节序与单词的意义无关。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-24
            • 2019-02-06
            • 2021-03-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多