代码之家  ›  专栏  ›  技术社区  ›  WonderCsabo

在Java中用C++等效语言读取浮点

  •  2
  • WonderCsabo  · 技术社区  · 7 年前

    我有一个二进制文件,应该包含32位浮点数。 这个文件是根据Objective-C代码编写的。 我的任务是用Java读取此文件。

    我想我是用C++做到的:

    #include <fstream>
    #include <iostream>
    
    int main() {
        float f;
        std::ifstream fin("effect_0.cube", std::ios::binary);
        while (fin.read(reinterpret_cast<char*>(&f), sizeof(float))) {
          std::cout << f << "\n";
        }
    
        return 0;
    }
    

    这就是我在Java中解释浮点的方式

    InputStream is = new FileInputStream("effect_0.cube");
    DataInputStream dataInputStream = new DataInputStream(is);
    float f = dataInputStream.readFloat();
    

    但这会返回完全错误的值。

    我正在OSX上运行所有这些。

    文件是 here 。它非常小。C++中的值似乎是正确的,因为它们在正确的范围内,但我在Java中得到了完全不同的值。我还提供 hexdump -n 16 -s 256 :

    0000100 00 00 00 00 91 90 90 3e 00 00 00 00 00 00 80 3f
    0000110
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Andreas dfa    7 年前

    C代码正在CPU中写入 endian order ,对于英特尔处理器来说 小恩迪亚

    DataInputStream 正在以网络字节顺序读取,即 大端元

    阅读的最佳方式 float 在Java中,可以控制endian顺序的值是使用 ByteBuffer

    示例代码:

    try (InputStream is = new FileInputStream("effect_0.cube")) {
        ByteBuffer buf = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN);
        for (int len; (len = is.read(buf.array())) == 4; ) {
            buf.rewind();
            float f = buf.getFloat();
            System.out.println(f);
        }
    }