Я пытаюсь написать синтаксический анализатор сохранения, который сохраняет числа с плавающей запятой с прямым порядком байтов, однако Java находится в старшем порядке, поэтому мне нужно преобразовать FP и обратно при записи, но это вызывает некоторые несоответствия в некоторых плавающихчисла точек.
Я попытался прочитать число с плавающей запятой, преобразовать в биты int, обратить биты int и затем преобразовать обратно в число с плавающей запятой.
и наоборот преобразовать число с плавающей точкой в необработанное intбиты, обращая биты int и затем возвращая обратно к плавающей точке.
public void test()
{
//file contents (hex) 0x85, 0x76, 0x7e, 0xbd, 0x7f, 0xd8, 0xa8, 0x3e, 0x2f, 0xcb, 0x8f, 0x3d, 0x06, 0x7c, 0x70, 0x3f
RandomAccessFile iRAF = new RandomAccessFile(new File("input.test"), "r");
RandomAccessFile oRAF = new RandomAccessFile(new File("output.test"), "rw");
byte[] input = new byte[16];
iRAF.readFully(input);
float[] floats = new float[4];
for (int i = 0; i < 4; i++)
{
floats[i] = readFloat(iRAF);
}
writeFloats(oRAF, floats);
byte[] output = new byte[16];
oRAF.seek(0);
oRAF.readFully(output);
if (Arrays.equals(input, output) == false)
{
System.err.println(toHex(input));
System.err.println(toHex(output));
}
}
private String toHex(byte[] bytes)
{
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (int i = 0; i < bytes.length; i++)
{
sb.append(String.format("%02x", bytes[i])).append(" ");
}
return sb.toString();
}
public float readFloat(RandomAccessFile raf) throws IOException
{
return Float.intBitsToFloat(Integer.reverseBytes(Float.floatToRawIntBits(raf.readFloat())));
}
public void writeFloats(RandomAccessFile raf, float... floats) throws IOException
{
for (int i = 0; i < floats.length; i++)
raf.writeFloat(Float.intBitsToFloat(Integer.reverseBytes(Float.floatToRawIntBits(floats[i]))));
}
Я ожидаю, что выход будет иметь точно такое же шестнадцатеричное значение, что и вход:
85 76 7e bd 7f d8 a8 3e 2f cb 8f 3d 06 7c 70 3f
, но фактический выход составляет:
85 76 7e bd 7f c0 00 00 2fcb 8f 3d 06 7c 70 3f
это из-за некоторой ошибки округления с плавающей запятой, или, возможно, при преобразовании это преобразование в значение NaN и не сохранение битов (хотя я бы подумал, что это то, чтоt Float.floatToRawIntBits () предназначен для.