1

C で 2 つの 32 ビット浮動小数点数を 1 つの 64 ビット数値に、またはその逆に変換する必要があります。これを達成する最善の方法は何ですか?

私は最善の方法と、32 ビットの float から 64 ビットの long に、またはその逆に変換する必要があるかどうかについて少し混乱しています。

助けていただければ幸いです。

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 ビットであり、 の代わりにそれを使用できますdouble(つまり、 を使用してstruct、囲んでいる を取り除き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 に答える