如何将三个小数字存储到一个双?

时间:2013-05-13 06:32:57

标签: math optimization double

我有int A, B, CA的范围为0-9999B0-99C0-99

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

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

6 个答案:

答案 0 :(得分:2)

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

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

89061234
CCBAAAA

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

希望这有帮助!

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

这在技术上不是合法的C代码,因此您需要自担风险:

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

C标准不允许使用union成员写一个值来读取它,但是我不知道有一个编译器执行静态分析来诊断这样的问题(它没有意味着将来不会这样做)。此外,使用某些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;
}

答案 3 :(得分:0)

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

答案 4 :(得分:0)

您可以使用尾数中存储的数据返回NaN double。这给你53位利用。应该是充足的。

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

答案 5 :(得分:0)

受到你的回答的启发,这是我到目前为止所提出的。这应该非常有效,并且仅使用32位,因此exponent的{​​{1}}不会被触及。

double