0

データベースから文字列として取得した経度と緯度を変換したいと考えています。文字列は正しく、double に変換しようとすると、これも正しいです。ただし、doubleまたはstring値(両方を試しました)をfloat値に変換すると、最後の小数点が丸められます。

string または double の値は 59.858139 です float への変換は 59.85814 です

私はすべてを試しましたが、これは絶望的な例の1つです:)

private float ConvertToFloat(double d)
{
    float f = 00.000000f;
    f = (float) d;
    return f;
}
4

3 に答える 3

7

ダブルスはフロートよりも精度が高く、フロートは四捨五入されていることをご存知ですか?これは予想される動作です。この場合、ダブルをフロートにキャストしても意味がありません。

これがあなたに正しい方向に考えさせるための何かです...

    Double.doubleToRawLongBits(long value);
    Float.intBitsToFloat(int bits);

ダブルスはintに収まらず、longに収まらなければなりません。それは実際には2倍のサイズであり、文字列でビットを仲介することでさえ、ここでは何の役にも立ちません。

于 2012-08-09T10:24:18.867 に答える
3

1. 精度は24ビットfloatしかないため、緯度と経度の桁数を保持するには不十分です。

2.四捨五入は、数値のサイズによるものです。したがってdouble、浮動小数点が必要な場合は使用するか、BigDecimal

于 2012-08-09T10:30:53.930 に答える
1

私たちはあなたの10進数から始めています59.858139

その数値を 2 進数に変換します。111011.11011011101011101111111101011100011011000001000110100001000100...

つまり、数値は 2 進法の無限分数です。正確に表現することはできません。(10 進数で 1/3 を正確に表すことができないのと同じように)

数値を何らかの形式の 2 進数科学表記法に書き直します。

10 ^ 101 * 1.1101111011011101011101111111101011100011011000001000110100001000100...

これはまだ 2 進数であるため、は 10 進数表記に10 ^ 101対応することに注意してください。2 ^ 5

さて... 浮動小数点値は、仮数部に 23 ビットを格納できます。「最も近いものに丸める」丸めモードを使用して切り上げると、次のようになります。

10 ^ 101 * 1.11011110110111010111100

これは次のようになります:

111011.110110111010111100

float データ型に収まる精度はこれだけです。これを 10 進数に変換します。

59.8581390380859375

実際には 59.858139 にかなり近いように見えます...しかし、それはただの運です。代わりに、2 番目に近い float 値をバイナリに変換するとどうなりますか?

111011.110110111010111011 = 59.858135223388671875

したがって、基本的に解像度は約0.000004です。

したがって、float 値から実際にわかることは、数値が次のようなものであるということだけです59.8581390.000002

59.858137またはの場合もあります59.858141

最後の桁はかなり不確かなので、最後の桁が float 値の精度の範囲外であることを理解するのに十分なほど印刷コードがスマートであると推測しているため、値は に丸められ59.85814ます。


ところで、あなた (私のように) 2 進数と 10 進数を手作業で変換するのが面倒な場合は、このコンバーターを使用できます。浮動小数点システムの詳細について詳しく知りたい場合は、浮動小数点表現に関するウィキペディアのページが優れたリソースです。

于 2012-08-09T12:07:14.960 に答える