我有int A, B, C
。 A
的范围为0-9999
,B
为0-99
,C
为0-99
。
因为该函数必须只返回一个double
,所以我想把它们全部放在一个数字中。否则我需要调用三次函数。
但我不能写一个有效的代码来做到这一点。这将被称为数百万次,因此它应该非常有效,但没有ASM。
我需要一个函数double pack3int_to_double(int A, int B, int C) {}
答案 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位利用。应该是充足的。
答案 5 :(得分:0)
受到你的回答的启发,这是我到目前为止所提出的。这应该非常有效,并且仅使用32位,因此exponent
的{{1}}不会被触及。
double