用int来打包long double

huangapple go评论106阅读模式
英文:

Packing long double with int

问题

在gcc/clang中,long double 占用10字节,但却占用了16字节。如果这个结构体能够占用16字节就好了,但实际上却占用了32字节,浪费了一半的带宽。

我尝试过使用union来合并这两个值,但是由于编译器假设整个16字节仅由long double 使用,有时编辑它会修改int

有没有好的解决方案来更紧凑地打包它们?

英文:

On gcc/clang, long double use 10 bytes but take 16 bytes. It'd be good if this struct is 16 bytes but it's actually 32 bytes, wasting half of bandwidth.

struct {
    long double x;
    int id;
};

I tried to union two values, but since compiler assumes the whole 16 bytes used only by the long double, editing it sometimes modifies int.

Any good solution to pack them finely?

答案1

得分: 1

On gcc/clang, long double use 10 bytes but take 16 bytes.

我认为你的意思是long double的存储大小为16字节,其中只有10字节对其数值有效(所以有6字节是填充)。

This would be primarily a property of the target ABI for which the compiler is building, not of the compilers themselves.

这主要取决于编译器正在构建的目标ABI,而不是编译器本身。

It'd be good if this struct is 16 bytes but it's actually 32 bytes, wasting half of bandwidth.

如果这个结构体是16字节的话会很好,但实际上它是32字节,浪费了一半的带宽。

Have you considered using double instead of long double?

你考虑过使用double而不是long double吗?

In any case, the union is the only way that C provides for two or more live objects to have overlapping storage, where neither object comprises the other. That does not serve the purpose of storing two overlapping values simultaneously. Suppose you knew that the first 10 bytes of a long double were the significant ones, and that the size of int is 4. You might then imagine doing something like this:

无论如何,union是C语言提供的唯一方式,使两个或更多活动对象具有重叠的存储空间,其中没有一个对象包含另一个对象。 这不适用于同时存储两个重叠的值的目的。假设你知道long double的前10个字节是重要的,而int的大小是4。然后,你可以想象这样做:

union problemmatic {
    long double x;
    struct {
        char padding[12];
        int id;
    }
};

But

但是

  • it is not safe to assume that writing to member x writes only the 10 significant bytes, leaving the others alone, and

  • 不能假设只写入成员x仅写入10个重要字节,而将其他字节保持不变,

  • it is not safe to assume that writing to x and then writing to id does not cause the stored value of x to be a trap representation

  • 不能假设写入x然后写入id不会导致x的存储值成为陷阱表示

That is, writing to either member could invalidate the other.

也就是说,写入任何一个成员都可能使另一个成员无效。

Bottom line: if you want to use less storage then use smaller data types (i.e. double rather than long double). If you're committed to the data types you're using now then their storage footprint is part of the package.

总之,如果你想使用更少的存储空间,那么使用较小的数据类型(即double而不是long double)。 如果你已经决定使用现在的数据类型,那么它们的存储占用是不可避免的一部分。

英文:

> On gcc/clang, long double use 10 bytes but take 16 bytes.

I think you mean that the storage size of long double is 16 bytes, of which only 10 are significant to its numeric value (so 6 are padding).

This would be primarily a property of the target ABI for which the compiler is building, not of the compilers themselves.

> It'd be good if this struct is 16 bytes but it's actually 32 bytes, wasting half of bandwidth.

Have you considered using double instead of long double?

In any case, the union is the only way that C provides for two or more live objects to have overlapping storage, where neither object comprises the other. That does not serve the purpose of storing two overlapping values simultaneously. Suppose you knew that the first 10 bytes of a long double were the significant ones, and that the size of int is 4. You might then imagine doing something like this:

union problemmatic {
    long double x;
    struct {
        char padding[12];
        int id;
    }
};

But

  • it is not safe to assume that writing to member x writes only the 10 significant bytes, leaving the others alone, and
  • it is not safe to assume that writing to x and then writing to id does not cause the stored value of x to be a trap representation

That is, writing to either member could invalidate the other.

Bottom line: if you want to use less storage then use smaller data types (i.e. double rather than long double). If you're committed to the data types you're using now then their storage footprint is part of the package.

答案2

得分: -1

union {
    long double x;
    struct {
        int reserved[3];
        int id;
    };
};
英文:
union {
    long double x;
    struct {
        int reserved[3];
        int id;
    };
};

huangapple
  • 本文由 发表于 2023年6月29日 18:48:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76580318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定