1

もともとVB.NETで書かれたプログラムをJavaに移植しています。32ビットフロートをリトルエンディアン順に格納するファイルから読み取っています。

元のプログラムはこれを行います:

Dim br As BinaryReader = ...
Dim f_vb As Single = br.ReadSingle

Javaはビッグエンディアンなので、floatに変換する前にバイトを逆にします。

RandomAccessFile raf = // ...
int i = raf.readInt();
int bigEndian = Integer.reverseBytes(i);
float f_java = Float.intBitsToFloat(bigEndian);

私が知る限りf_vbf_java同じビットが含まれています。つまり、BitConverter.ToInt32onf_vbFloat.floatToIntBits(およびfloatToRawIntBits)onf_javaは同じことをします。ただし、フロートは等しくありません。たとえば、bigEndian == 0x4969F52F。Javaが報告958290.94し、VB.NETが報告し958290.938ます。これは、JVMとCLRが浮動小数点数を処理する方法の違いによるものだと思いますが、浮動小数点の問題については、その理由を理解するのに十分な知識がありません。この精度の低下が問題を引き起こしているので、原因を特定したいと思います。

4

1 に答える 1

6

これらのビットで表される正確な値は958290.9375です。「958290.94」を表示したJavaで値を表示するために使用したものはすべて、デフォルトで小数点以下2桁または有効数字8桁に丸められ、「958290.938」を表示したVB.NETで使用したものはすべてデフォルトで丸められる可能性があります。小数点以下3桁または有効数字9桁まで。あるいは、そのうちの1つは、浮動小数点を10進数に変換して表示するのが不十分な場合があります。

より多くの桁を表示するオプションがある場合は、それらを試してください。または、値958290.9375を作成し、それをf_javaから減算して、結果が正確にゼロであるかどうかをテストします。そのはず。

958290.9375に最も近い単精度浮動小数点数は958290.875と958291です。どちらも中途半端なフォーマッターでは「958290.94」または「958290.938」として表示されないため、使用している浮動小数点数が958290.9375以外である可能性はほとんどありません。

于 2012-07-14T03:35:01.573 に答える