我正在将最初用VB.NET编写的程序移植到Java。我正在从以小尾数顺序存储32位浮点数的文件中读取。
原始程序执行此操作:
Dim br As BinaryReader = ...
Dim f_vb As Single = br.ReadSingle
Java是大尾数法,因此在转换为浮点数之前,我先反转字节。
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处理浮点数的方式不同而引起的,但是我对浮点数的了解还不足以找出原因。精度的下降会带来麻烦,因此,我想找出原因。 最佳答案
这些位代表的确切值是958290.9375。可能是您用来显示Java值的任何内容(默认显示为“ 958290.94”)默认四舍五入到两位小数或八个有效数字,以及您在VB.NET中使用的任何内容(默认显示为“ 958290.938”)都默认四舍五入到小数点后三位或九位有效数字。或者,其中之一可能不擅长将浮点数转换为十进制显示。
如果有显示更多数字的选项,请尝试。或者,构造值958290.9375,从f_java中减去它,然后测试结果是否恰好为零。它应该是。
最接近958290.9375的单精度浮点数是958290.875和958291。任何中途的格式化程序都不能将其显示为“ 958290.94”或“ 958290.938”,因此您所拥有的浮点数不太可能是958290.9375之外的任何其他数字。