64 位整数中的 C++ 位

标签 c++ bitwise-operators

你好,我这里有一个 7 字节的结构,我想将它写入一个 64 位整数。接下来,我想稍后从 64 位整数中提取出这个结构。

对此有什么想法吗?

#include "stdafx.h"

struct myStruct
{
        unsigned char a;               
        unsigned char b;
        unsigned char b;
        unsigned int someNumber;
};

int _tmain(int argc, _TCHAR* argv[])
{
    myStruct * m = new myStruct();
    m->a = 11;
    m->b = 8;
    m->c = 12;
    m->someNumber = 30;

    printf("\n%s\t\t%i\t%i\t%i\t%i\n\n", "struct", m->a, m->b, m->c, m->someNumber);

    unsigned long num = 0;

    // todo: use bitwise operations from m into num (total of 7 bytes) 

    printf("%s\t\t%i\n\n", "ulong", num);

    m = new myStruct();

    // todo: use bitwise operations from num into m;

    printf("%s\t\t%i\t%i\t%i\t%i\n\n", "struct", m->a, m->b, m->c, m->someNumber);

    return 0;
}

最佳答案

你应该这样做:

class structured_uint64
{
    uint64_t data;
public:
    structured_uint64(uint64_t x = 0):data(x) {}
    operator uint64_t&() { return data; }
    unsigned uint8_t low_byte(size_t n) const { return data >> (n * 8); }
    void low_byte(size_t n, uint8_t val) {
        uint64_t mask = static_cast<uint64_t>(0xff) << (8 * n);
        data = (data & ~mask) | (static_cast<uint64_t>(val) << (8 * n));
    }
    unsigned uint32_t hi_word() const { return (data >> 24); }
    // et cetera
};

(当然,在接口(interface)的细节和 64 位中的组成部分的位置上还有很大的变化空间)

使用不同的类型来别名内存的同一部分通常是一个坏主意。问题是,优化器能够使用如下推理非常有值(value):

"Okay, I've read a uint64_t at the start of this block, and nowhere in the middle does the program write to any uint64_ts, therefore the value must be unchanged!"

这意味着如果您尝试通过 uint32_t 引用更改 uint64_t 对象的值,它将得到错误的答案。由于这非常依赖于哪些优化是可能的和已完成,实际上很容易在测试用例中永远不会遇到问题,但在您尝试编写的真实程序中会看到它——您将永远尝试找到错误,因为您确信这不是这个问题。

因此,您真的应该使用位旋转(或内在函数,如果分析显示这是一个性能问题并且有可用的可用问题)而不是尝试设置一个聪明的结构来插入/提取字段。

如果您真的知道自己在做什么,我相信您可以使用别名。但只有当您真的知道自己在做什么时才应该这样做,这包括从内到外了解标准的相关规则(我不知道,所以我不能建议您关于如何让它发挥作用)。即便如此,您也可能不应该这样做。

此外,如果您希望整数类型具有特定大小,您应该确实使用正确的类型。例如,切勿将 unsigned int 用于应该正好是 32 位的整数。而是使用 uint32_t。它不仅是 self 记录的,而且当您尝试在 unsigned int 不是 32 位的环境中构建程序时,您也不会遇到令人讨厌的惊喜。

关于64 位整数中的 C++ 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11044254/

相关文章:

c++ - 析构函数向后兼容 noexcept(false)

c - 错误: invalid operands to binary >> (have 'float' and 'int' )

c++ - 哈希表 : Double hashing when the second hash function returns a multiple of the table size

c++ - 无法从静态初始化代码启动 CUDA 内核

c++ - 如何在顶点着色器中使用 LookAt 矩阵

c++ - 使用 getline 的 csv 处理行为不明确

c - 如何通过按位运算尽可能精确地计算C中整数的log2

arrays - Swift Array[UInt8] 使用按位运算符不起作用?

c++ - 如何在 linux 中对文件执行位操作?

c - 我如何在 C 中的字符指针上应用 << 运算符和++ 运算符