我正在将最初用VB.NET编写的程序移植到Java。我正在读取一个以小端顺序存储32位浮点数的文件。
原始程序执行此操作:
Dim br As BinaryReader = ...
Dim f_vb As Single = br.ReadSingle
Java是big endian,所以我在转换为float之前反转字节。
RandomAccessFile raf = // ...
int i = raf.readInt();
int bigEndian = Integer.reverseBytes(i);
float f_java = Float.intBitsToFloat(bigEndian);
据我所知,f_vb
和f_java
包含相同的位。也就是说,BitConverter.ToInt32
上的f_vb
和Float.floatToIntBits
上的floatToRawIntBits
(以及f_java
)给出相同的内容。但是,花车并不相同。例如,让bigEndian == 0x4969F52F
。 Java将报告958290.94
,VB.NET将报告958290.938
。我猜这是因为JVM和CLR处理浮点数的方式有所不同,但我对浮点问题知之甚少以找出原因。这种精度的损失正在引起麻烦,所以我想确定来源。
答案 0 :(得分:6)
这些位表示的确切值是958290.9375。可能是你用来显示Java中的值,显示“958290.94”,默认情况下舍入到两位小数或八位有效数字,以及你在VB.NET中使用的任何显示“958290.938”的值,默认情况下舍入小数点后三位或九位有效数字。或者,其中一个可能很难将浮点数转换为十进制数。
如果有选项可以显示更多数字,请尝试使用它们。或者,构造值958290.9375,从f_java中减去它,并测试结果是否正好为零。应该是。
最接近958290.9375的单精度浮点数是958290.875和958291.任何一个正常的格式化程序都不能将它们显示为“958290.94”或“958290.938”,因此你拥有的浮点数不太可能是其他比958290.9375。