如何访问 "int20_t" 中的数据?

How do I access data in "int20_t"?

我得到了很多512位的内存片。我需要写 20 位的数字。

例如:

// a piece of 512 bits memory
void *p = malloc(64);

struct Coords {
  int20_t x, y;
};

// usage
Coords *pcoord = (Coords *)p;

for (int i = 0; i < 512 / 40/*sizeof(Coords)*/; ++i) {
  pcoord[i].x = i;
  pcoord[i].y = 2 * i;
}

如何实现int20_t

我正好需要 20 位的整数。数字必须是连续的。 ( [0] 到 [19] 为第一个 Coords.x; [20]至[39]为第Coords.y; ... 有12对480位的Coords和32位的焊盘。)

你不能。在 int20_t x, y; 中,您需要分数对齐(除非您有 10 位硬件)。

基本原理是 &y 必须是 int20_t*,可转换为 void*

您可以为整个 480 位创建一个包装类型,operator[]

类型 int20_t 仅适用于具有 20 位寄存器的非常特殊的硬件。你不需要这种类型来处理你的数据,你可以使用普通的 int 来存储坐标或者可能使用 bit-fields 但这似乎没有必要。

主要问题是从外部表示(512 位块中的 12 对 20 位值)转换为更易于管理的内存表示作为结构数组,也可能是相反的方式。

要处理此转换,您必须准确指定位在 64 字节块中的打包方式。每个值将分为 3 个部分,必须指定这些字节和最后一个字节字节中的位的顺序。

这是一个示例,其中值以大端格式存储,第三个字节在其高位中包含 x 的低位,在其高位中包含 y 的高位低位:

struct Coords {
    int x, y;
};

void load_coords(struct Coords *a, const unsigned char *p) {
    for (int i = 0; i < 20; i++) {
        a->x = (p[0] << 12) + (p[1] << 4) + (p[2] >> 4);
        a->y = ((p[2] & 15) << 16) + (p[3] << 8) + p[4];
        p += 5;
        a++;
    }
}

void store_coords(unsigned char *p, const struct Coords *a) {
    for (int i = 0; i < 20; i++) {
        p[0] = a->x >> 12;
        p[1] = a->x >> 4;
        p[2] = (a->x << 4) | ((a->y >> 16) & 15);
        p[3] = a->y >> 8;
        p[4] = a->y;
        p += 5;
        a++;
    }
}