1

我有int A, B, C。并且A在范围内0-9999B0-99C0-99

因为函数必须只返回一个double,所以我想把它们都放在一个数字中。否则我需要调用函数三次。但我无法编写有效的代码来做到这一点。这将被调用数百万次,因此它应该非常有效,但没有 ASM。

我需要一个函数double pack3int_to_double(int A, int B, int C) {}

4

6 回答 6

2

你不能只存储 A + 1000B + 100000C 吗?

例如,如果您想存储 A = 1234、B = 6 和 C = 89,则只需存储

89061234
CCBAAAA

然后,您可以通过将 double 转换为 anint并使用标准整数除法和模数技巧来恢复各个值来提取数字。

希望这可以帮助!

于 2013-05-13T06:35:29.970 回答
2

如果 A<10,000 且 B & C <100,则 A 可以用 14 位表示,B & C 可以用 8 位表示。因此,您总共需要 30 位。
因此,您可以通过将整数移动到正确的位置来打包/解包整数:

int packed = A + B<<14 + C<<22;  
A = packed & 0x3FFF; B = (packed >> 14) & 0xFF; C = (packed >> 22) & 0xFF;

位移当然比乘法/除法快得多,您可以将 int 转换为 double ,反之亦然。

于 2013-05-13T07:00:45.123 回答
1

从技术上讲,这不是合法的 C 代码,因此您将自担风险使用它:

typedef union {
    double x;
    struct {
        unsigned a : 14;
        unsigned b : 7;
        unsigned c : 7;
    } y;
} result_t;

C 标准不允许使用联合成员写入值并使用不同的成员将其读出,但我不知道有编译器会进行静态分析来诊断此类问题(这并不意味着赢了以后不要这样做)。此外,使用某些int值可能会导致double. 但是,如果您知道您的系统不会生成任何陷阱表示,您可以考虑使用它。

double pack3int_to_double(int A, int B, int C) {
    result_t r;
    r.y.a = A;
    r.y.b = B;
    r.y.c = C;
    return r.x;
}

void unpack3int_from_double (double X, int *A, int *B, int *C) {
    result_t r = { X };
    *A = r.y.a;
    *B = r.y.b;
    *C = r.y.c;
}
于 2013-05-13T06:50:16.880 回答
0

受您的回答的启发,这就是我到目前为止的想法。这应该是相当高效的,并且只使用了 32 位exponent,所以double不会触及 的 。

struct pack_abc {
    unsigned short a;
    unsigned char b, c;
    int safety;
};

double pack3int_to_double(int A, int B, int C) {
    struct pack_abc R = {A, B, C, 0}; // or 0 could be replaced with something smater, like NaN?
    return *(double*)&R;
}

void main() {
    int w = 1234, a = 56, d = 78;
    int W, A, D, i;
    double p = pack3int_to_double(w, a, d);
    // we got the data packed into 'p', now let's unpack it
    struct pack_abc *R = (struct pack_abc*) & p;
    printf("%i %i %i\n", (int)R->a, (int)R->b, (int)R->c);
}
于 2013-05-13T07:16:39.747 回答
0

您可以在函数调用中使用 out 参数并检索所有 3 个 int 变量。

于 2013-05-13T06:41:39.527 回答
0

您可以使用存储在尾数中的数据返回 NaN 双精度值。这为您提供了 53 位可供使用。应该很多。

http://en.m.wikipedia.org/wiki/NaN

于 2013-05-13T06:49:33.907 回答