JAva FloatとDouble間の相互転換問題


floatは単精度浮動小数点でありdoubleは二精度浮動小数点である
単精度型は7ビットまで正確で、二重精度は15ビットまで正確である.ユーザーは、これらのデータ型を選択する際に、変数の値の範囲に注意します.また、数値が整数の場合、演算速度のために変数を浮動小数点型としてハード定義する必要はありません.
FloatとDoubleを互いに変換する場合、javaはFloat.doubleValue()とDouble.floatValue()の方法を提供します.
JDK 1.6でのメソッドの表示
Float.doubleValue()
public double doubleValue()

ここに戻るFloatオブジェクトのdoubleの値です.
指定者:
クラス#クラス#NumberdoubleValue
戻り値:
このオブジェクトはfloatの値はdoubleタイプで、変換の結果を返します.
Double.floatValue()
public float floatValue()

ここに戻るDoubleオブジェクトのfloatの値です.
指定者:
クラス#クラス#NumberfloatValue
戻り値:
変換float型のこのオブジェクトによって表されるdouble
次のバージョンから開始します.
JDK1.0
まず簡単な例から説明します.
public static void main(String[] args) {
		Float f=new Float(14.1);
		System.out.println(f.floatValue());
		System.out.println(f.doubleValue());
		
		Double d = new Double(14.1);
		System.out.println(d.floatValue());
		System.out.println(d.doubleValue());
	}

出力の結果は次のとおりです.
14.1
14.100000381469727
14.1
14.1

このとき、Float.doubleValue()が見られる場合、数字は不正確で14.1であるべきであり、結果は14.100000381469727であり、これが単精度回転二精度の場合、二精度が単精度を補位する.偏差が生じる.
私のこの時の解決策はこうだった.
Float f=new Float(14.1);
System.out.println(f.floatValue());
System.out.println(f.doubleValue());
System.out.println(Double.parseDouble(f.floatValue()+""));
出力の結果
14.1
14.100000381469727
14.1

次の例を見てみましょう
	public static void main(String[] args) {
		Float f=new Float(14.111111111111111111111111);
		System.out.println(f.floatValue());
		System.out.println(f.doubleValue());
		
		Double d = new Double(14.111111111111111111111111);
		System.out.println(d.floatValue());
		System.out.println(d.doubleValue());
	}

出力結果:
14.111111
14.11111068725586
14.111111
14.11111111111111

このとき、小数点以下の桁数が長すぎるため、Float単精度とDouble両精度の両方を一度にカットして計算したところ、Float.doubleValue()は依然として補位問題が発生していたが、今回の補位では元のデータを破壊してしまった.
誤差を減らすためにFloatのデータをdoubleデータに変換する場合は、やはり前の操作方法を採用します
System.out.println(Double.parseDouble(f.floatValue()+""));
出力の結果は
14.111111

次の例を見てみましょう
	public static void main(String[] args) {
		Float f=new Float(14.6666666666666666666666666666666666666);
		System.out.println(f.floatValue());
		System.out.println(f.doubleValue());
		
		System.out.println(Double.parseDouble(f.floatValue()+""));
		
		Double d = new Double(14.6666666666666666666666666666666666666);
		System.out.println(d.floatValue());
		System.out.println(d.doubleValue());
	}

出力の結果は
14.666667
14.666666984558105
14.666667
14.666667
14.666666666666666

このとき,与えられたデータが単精度のビット数を超えると切り取られ,切り取った数字の残りの第1位が5より大きい場合,必然的に進位(すなわち最後のビット+1),5より小さい場合,必然的に進位しない(すなわち最後のビットは変わらない)ことが分かった.
一方、切り取った数字の残りの1位が5に等しい場合、進位する場合もあり、進位しない場合もある.(ソースコードを確認し、原因が見つからなかった)
二重精度この値では進位しません
次の例を見てみましょう
	public static void main(String[] args) {
		Float f=new Float(14.777777777777777777777777);
		System.out.println(f.floatValue());
		System.out.println(f.doubleValue());
		
		System.out.println(Double.parseDouble(f.floatValue()+""));
		
		Double d = new Double(14.77777777777777777777777777777);
		System.out.println(d.floatValue());
		System.out.println(d.doubleValue());
	}

このときの結果
14.777778
14.777777671813965
14.777778
14.777778
14.777777777777779

従って,大量のデータのテストでは,単精度でも二精度でも正確なキャリーは決定できないことが分かった.
まとめ
単精度回転二精度の場合は補位問題の採用を防止していない
Double.parseDouble(f.floatValue()+"")
単一精度データの正確性を保持
一方,二重精度で単精度を回転させた場合,誤ったデータは発見されなかった.基本的には単精度と同じです.
やっと書き終わりました...この文章は主に初心者たちに読んだものです.のもっと良い解決策があれば直接コメントしてもいいです...みんなが勉强できるように...