首页 文章

Java是以小端还是大端读取整数?

提问于
浏览
88

我问,因为我正在从C进程向Java发送字节流 . 在C端,32位整数的LSB是第一个字节,MSB是第4个字节 .

所以我的问题是:在Java端,当我们读取从C进程发送的字节时,Java端的endian是什么?

一个后续问题:如果Java端的endian与发送的端不一样,我怎样才能在它们之间进行转换?

6 回答

  • 42

    使用网络字节顺序(big endian),这与Java使用的相同 . 请参阅C中的不同翻译人员 .

  • 11

    我在这里偶然发现了谷歌并得到了我的答案,即Java是大端 .

    阅读回复我想指出字节确实有一个字节顺序,尽管如果你只处理“主流”微处理器,你不可能像英特尔,摩托罗拉和Zilog那样遇到它同意他们的UART芯片的移位方向,并且一个字节的MSB将是2 ** 7并且LSB在他们的CPU中将是2 ** 0(我使用FORTRAN功率符号来强调这些东西的年龄:)) .

    20年前,当我们用Mac计算机替换了 Value 10美元的接口硬件时,我遇到了一些航天飞机位串行下行链路数据 . 很久以前就有一篇关于它的NASA技术简报 . 在每个字节从位流中移入后,我只使用256元素查找表,其中位反转(表[0x01] = 0x80等) .

  • 60

    Java中没有无符号整数 . 所有整数都是签名的大端 .

    在C侧,每个字节的开头的LSB在左边,MSB在最后 .

    听起来你使用LSB作为最不重要的一点,是吗? LSB通常代表最低有效字节 . Endianness不是基于位的,而是基于字节的 .

    要从无符号字节转换为Java整数:

    int i = (int) b & 0xFF;
    

    要从byte []中的无符号32位little-endian转换为Java long(从头顶开始,未经测试):

    long l = (long)b[0] & 0xFF;
    l += ((long)b[1] & 0xFF) << 8;
    l += ((long)b[2] & 0xFF) << 16;
    l += ((long)b[3] & 0xFF) << 24;
    
  • 18

    这无法影响Java中的任何东西,因为没有(直接的非API)方法将一些字节直接映射到Java中的int .

    执行此操作或类似操作的每个API都非常精确地定义了行为,因此您应该查找该API的文档 .

  • 2

    我会逐个读取字节,并将它们组合成 long 值 . 这样您就可以控制字节顺序,并且通信过程是透明的 .

  • 3

    如果它符合您使用的协议,请考虑使用DataInputStream,其行为是very well defined .

相关问题