在宏中指定int大小(或其他)。

问题描述 投票:1回答:1

我想把3个整数(即每一个21位)存储在一个 long int 与这些宏。

typedef long int Triple;
#define TR_A(o) ((int)((o & 0x7FFFFC0000000000) >> 42))
#define TR_B(o) ((int)((o & 0x000003FFFFE00000) >> 21))
#define TR_C(o) ((int)(o & 0x00000000001FFFFF))
#define MK_TR(a,b,c) ((long int)((a<<42) & (b<<21) & c))

所以我们的想法是 o 是64位,而 a,b,c 各为32个。当存储在 o 它们是21位,64位是空位。a, b,然后 c.

我得到一堆这样的错误。

warning: left shift count >= width of type [-Wshift-count-overflow]
 #define MK_TR(a,b,c) ((long int)((a<<42) & (b<<21) & c))
                                    ^

能否在里面添加一些东西 TR_ATR_BTR_C 其中规定 o 是长?

有什么更好的方法吗?

我希望能够将这些值作为简单的值返回,而不是指针。在PC上使用Linux。

c 64-bit x86-64 bit bit-shift
1个回答
0
投票

为了支持+- 1M范围内的两补号有符号的ints,需要进行掩码和移位。

inline uint64_t make64(int a, int b, int c) {
    return ((uint64_t) (a & 0x1fffff) << 42) |
           ((uint64_t) (b & 0x1fffff) << 21) |
           ((uint64_t) c & 0x1fffff)

当拆分时,12个符号位将需要被恢复。

inline int32_t get_a(uint64_t t) {
    return (int32_t)((t >> 42 & 0xfffff) | (t & 0x4000000000000000) ? 0xfff00000 : 0);
etc.

3
投票

你可以指定一个整数文字(常数)应该被解释为一个... long int 加上 L 后缀(或小写 l - 但这看起来太像一个 1 为了我的舒适)。) 同样,对于一个 long long int,添加 LL 后缀。

在你的宏的情况下,你还需要显式地投掷参数。a, bc 到适当的(longlong long)类型。

然而,与其依靠特定的编译器来实现 long int 作为64位类型(许多编译器没有这样做,而是使用32位类型来处理 intlong int并要求 long long int 对于64位类型),你应该使用位宽的 特定 中定义的类型。<stdint.h> 头文件。

因此,下面的代码应该是无警告的 和便携式:

#include <stdint.h>

typedef int64_t Triple;
#define TR_A(o) ((int32_t)(((int64_t)(o) & 0x7FFFFC0000000000LL) >> 42))
#define TR_B(o) ((int32_t)(((int64_t)(o) & 0x000003FFFFE00000LL) >> 21))
#define TR_C(o) ((int32_t)((int64_t)(o) & 0x00000000001FFFFFLL))
// EDIT/NOTE: I have changed the bitwise & operations to | in the macro below,
// as this is probably what you actually want (otherwise it will give 0 always)!
#define MK_TR(a,b,c) ((int64_t)(((int64_t)(a) << 42) | ((int64_t)(b) << 21) | (int64_t)(c)))

另外,最好的做法是始终把宏参数放在括号里(如 (c) 在上面最后一行)。) 如果没有这个功能,对您的宏的调用就会出现一个带有 表情 作为一个论据,可能会给你带来意想不到的结果,这可能是难以追踪的。这将是一个很好的例子。

int a = 1, b = 2, c = 3;
Triple test = MK_TR(a + 1, b + 1, c + 1); // Unexpected(?) result.
© www.soinside.com 2019 - 2024. All rights reserved.