Math 如何将三个小数字存储为一个双精度?

Math 如何将三个小数字存储为一个双精度?,math,optimization,double,Math,Optimization,Double,我有inta,B,C。而A在0-9999范围内,B在0-99范围内,C在0-99范围内 因为函数必须只返回一个双精度,所以我考虑将它们全部放在一个数字中。否则我需要调用函数三次。 但我无法编写有效的代码来实现这一点。这将被调用数百万次,因此它应该非常有效,但没有ASM 我需要一个函数double pack3int\u to\u double(inta,intb,intc){}你不能只存储a+1000B+100000C吗 例如,如果您想存储A=1234、B=6和C=89,您只需存储 8906123

我有
inta,B,C
。而
A
0-9999
范围内,
B
0-99
范围内,
C
0-99
范围内

因为函数必须只返回一个
双精度
,所以我考虑将它们全部放在一个数字中。否则我需要调用函数三次。
但我无法编写有效的代码来实现这一点。这将被调用数百万次,因此它应该非常有效,但没有ASM


我需要一个函数
double pack3int\u to\u double(inta,intb,intc){}

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

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

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


希望这有帮助

你就不能存储A+1000B+10000C吗

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

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


希望这有帮助

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

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

您可以使用存储在尾数中的数据返回一个NaN double。这样就有53位可供利用。应该足够了


您可以返回一个包含尾数中存储的数据的NaN double。这样就有53位可供利用。应该足够了


这在技术上不是合法的C代码,因此使用此代码的风险由您自己承担:

typedef union {
    double x;
    struct {
        unsigned a : 14;
        unsigned b : 7;
        unsigned c : 7;
    } y;
} result_t;
C标准不允许使用一个联合成员来编写一个值,而使用另一个成员来读取它,但我不知道有哪个编译器会进行静态分析来诊断这样的问题(这并不意味着将来不会这样做)。此外,使用某些
int
值可能会导致双精度
的陷阱表示。但是,如果你知道你的系统不会产生任何陷阱表示,你可以考虑使用这个。
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;
}

这在技术上不是合法的C代码,因此使用此代码的风险由您自己承担:

typedef union {
    double x;
    struct {
        unsigned a : 14;
        unsigned b : 7;
        unsigned c : 7;
    } y;
} result_t;
C标准不允许使用一个联合成员来编写一个值,而使用另一个成员来读取它,但我不知道有哪个编译器会进行静态分析来诊断这样的问题(这并不意味着将来不会这样做)。此外,使用某些
int
值可能会导致双精度
的陷阱表示。但是,如果你知道你的系统不会产生任何陷阱表示,你可以考虑使用这个。
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;
}

如果A如果A受到你答案的启发,这就是我到目前为止提出的问题。这应该是非常有效的,并且只使用32位,因此不会触及
双精度
指数

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);
}

受你答案的启发,这就是我目前提出的问题。这应该是非常有效的,并且只使用32位,因此不会触及
双精度
指数

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);
}


调用函数三次。拜托,这不可能帮你节省时间。打包和解包速度较慢。请调用该函数三次。拜托,这不可能帮你节省时间。打包和解包都很慢。这正是我想要做的,但我仍然在寻找一个高效的C代码。我想它应该与乘法、除法和舍入有关。但是最有效的代码是什么?如果B=96和C=9呢?它将是:8961234 CBBAAA,永远不会起作用。这个想法仍然是正确的,只要修正公式。@FrancescoDeLisi-我的道歉-我误读了OP的问题,认为B总是一位数。答案更新@templatetypedef公式很容易修正,但概念在起点是错误的。三次调用同一个公式并不比一次调用一个将n个数字打包成一个的公式更昂贵。这正是我想要做的,但我仍然在寻找一个高效的C代码。我想它应该与乘法、除法和舍入有关。但是最有效的代码是什么?如果B=96和C=9呢?它将是:8961234 CBBAAA,永远不会起作用。这个想法仍然是正确的,只要修正公式。@FrancescoDeLisi-我的道歉-我误读了OP的问题,认为B总是一位数。答案更新@templatetypedef公式很容易修正,但概念在起点是错误的。三次调用同一个公式并不比一次调用一个包含n个数字的公式更昂贵。同时,向一个工会的一个成员写信,然后再读取另一个是未定义的行为,对吗?现在每一个主流编译器都会支持这种行为,但仍然需要记住。谢谢,这看起来很有趣,但我不明白如何使用它@更新了答案。同时,给工会的一个成员写信,然后又读另一个是未定义的行为,不是吗?现在每一个主流编译器都会支持这种行为,但仍然需要记住。谢谢,这看起来很有趣,但我不明白如何使用它@exebook:更新了答案。+1为了认识到打包不需要double,它可以是返回类型。浮点乘法实际上非常快——就像单周期快一样——你不需要任何除法,只需要用0.00001之类的数字进行乘法。另一方面,在某些体系结构上,将数字从浮点寄存器移动到整数寄存器的成本可能相当高。+1为了实现不需要打包double,它可以是返回类型。浮点乘法实际上非常快——就像单周期快一样——而且不需要任何除法,只需乘以数字,比如0.00001。另一方面,从浮点寄存器中移动一个数字