1

我需要在 C 中将两个 32 位浮点数转换为一个 64 位数字,反之亦然。实现这一目标的最佳方法是什么?

我对最好的方法有点困惑,如果我应该从 32 位的浮点数转换为 64 位的长整数,反之亦然。

帮助表示赞赏。

4

1 回答 1

4

如果您正在谈论以某种方式在数学上组合它们(例如加法),您可以先将它们强制为 64 位:

float pi = 3.141592653589;
float e  = 2.718281828459;
double sum = (double)pi + (double)e;

我猜这不是您想要的,因为正如评论中有人指出的那样,如果您所拥有的只是它们的总和,那么很难恢复到原始值。


如果您只是简单地按顺序组合位,则可以执行以下操作:

#include <stdio.h>

union {
    struct {
        float f1;
        float f2;
    };
    double d;
} xyzzy;

int main (void) {
    xyzzy.f1 = 3.141592653589;
    xyzzy.f2 = 2.718281828459;
    double d2 = xyzzy.d;

    printf ("%lf\n", xyzzy.d);

    xyzzy.f1 = 0;
    xyzzy.f2 = 0;
    xyzzy.d = d2;

    printf ("%f %f\n", xyzzy.f1, xyzzy.f2);
}

输出:

14.985018
3.141593 2.718282

尽管您应该记住,这种行为(类型双关语)是根据它是否会起作用而定义的实现。在任何情况下,如果float值是 32 位大小和对齐方式,则内部struct本身几乎肯定是 64 位,您可以使用它来代替 the double(换句话说,使用 thestruct并去掉封闭的union)。

如果您想要一些可以为您完成繁重工作的功能,请参见下文:

#include <stdio.h>

double cvtToDbl (float n1, float n2) {
    struct { float n1; float n2; } s;
    s.n1 = n1;
    s.n2 = n2;
    return *((double*)&s);
}

void cvtToFlts (double d, float *pn1, float *pn2) {
    struct { float n1; float n2; } *ps = (void*)&d;
    *pn1 = ps->n1;
    *pn2 = ps->n2;
}

int main (void) {
    float f1 = 0, f2 = 0;
    double d = cvtToDbl (3.141592653589, 2.718281828459);
    printf ("%lf\n", d);

    cvtToFlts (d, &f1, &f2);
    printf ("%f %f\n", f1, f2);

    return 0;
}
于 2012-08-06T08:30:12.117 回答