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

Java是以小尾数还是大尾数读取整数?,java,endianness,Java,Endianness,我这样做是因为我正在从C进程向Java发送一个字节流。在C端,32位整数的LSB是第一个字节,MSB是第四个字节 所以我的问题是:在Java端,当我们读取从C进程发送的字节时,Java端是什么 接下来的一个问题是:如果Java端的endian与发送的endian不同,如何在它们之间进行转换?Java中没有无符号整数。所有整数都是有符号的,并且以大端为单位 在C端,每个字节的开头都有LSB,左边是LSB,末尾是MSB 听起来像是在使用LSB作为最低有效位,是吗?LSB通常表示最低有效字节。 不是基

我这样做是因为我正在从C进程向Java发送一个字节流。在C端,32位整数的LSB是第一个字节,MSB是第四个字节

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


接下来的一个问题是:如果Java端的endian与发送的endian不同,如何在它们之间进行转换?

Java中没有无符号整数。所有整数都是有符号的,并且以大端为单位

在C端,每个字节的开头都有LSB,左边是LSB,末尾是MSB

听起来像是在使用LSB作为最低有效位,是吗?LSB通常表示最低有效字节。 不是基于位,而是基于字节

要将无符号字节转换为Java整数,请执行以下操作:

int i = (int) b & 0xFF;
要将字节[]中的无符号32位低位字节转换为Java long(从头顶开始,未测试):

long l=(long)b[0]&0xFF;

l+=((long)b[1]&0xFF)我将逐个读取字节,并将它们组合成一个long值。通过这种方式,您可以控制端点,并且通信过程是透明的。

使用网络字节顺序(big-endian),这与Java使用的方式相同。请参阅java语言中的不同版本的人Htnts。如果它符合您使用的协议,考虑使用DATAINPUSTRAW,行为是.< /P> < P>这不可能影响Java中的任何东西,因为没有(直接非API)的方式将一些字节直接映射到int中的java。
每一个这样做的API或类似的API都非常精确地定义了行为,因此您应该查找该API的文档。

我在这里通过Google无意中发现了Java是big-endian

通过阅读回复,我想指出字节确实有一个endian顺序,尽管幸运的是,如果你只处理过“主流”微处理器,你不太可能遇到像英特尔、摩托罗拉、,Zilog和Zilog都同意UART芯片的移位方向,在他们的CPU中,一个字节的MSB将是
2**7
,LSB将是
2**0
(我使用FORTRAN幂表示法强调这东西有多旧:)


20多年前,当我们用一台Mac电脑替换一个价值10万美元的接口硬件时,我遇到了一些航天飞机位串行下行链路数据的问题。很久以前,美国宇航局发布了一份技术简报。我只是使用了一个256元素的查找表,在从位流中移入每个字节后,将位反转(
table[0x01]=0x80
等)。

如上所述,Java是“Big-endian”。这意味着,如果检查内存(至少在英特尔CPU上),int的MSB位于左侧。符号位也位于所有Java整数类型的MSB中
在Java中,从“Little endian”系统存储的二进制文件中读取4字节无符号整数需要一些调整。DataInputStream的readInt()需要大端格式。
以下示例将四字节无符号值(由HexEdit显示为01 00 00)读取为值为1的整数:

 // Declare an array of 4 shorts to hold the four unsigned bytes
 short[] tempShort = new short[4];
 for (int b = 0; b < 4; b++) {
    tempShort[b] = (short)dIStream.readUnsignedByte();           
 }
 int curVal = convToInt(tempShort);

 // Pass an array of four shorts which convert from LSB first 
 public int convToInt(short[] sb)
 {
   int answer = sb[0];
   answer += sb[1] << 8;
   answer += sb[2] << 16;
   answer += sb[3] << 24;
   return answer;        
 }
//声明一个包含4个短字符的数组,以保存四个无符号字节
short[]tempShort=新的short[4];
对于(int b=0;b<4;b++){
tempShort[b]=(short)dIStream.readUnsignedByte();
}
int curVal=convToInt(tempShort);
//传递一个由四条短裤组成的数组,这些短裤首先从LSB转换而来
公共int convToInt(短[]sb)
{
int-answer=sb[0];


答案+=sb[1]java force确实是big-endian:

刚刚意识到:$那么我应该如何将这个无符号的小endian发送到我的java进程以正确读取它呢?我所说的开始是指lsb在4个字节的开始处(它是一个无符号的32位int)所以我的意思是最不重要的byteals,所以我是从C->Java转换而不是从Java->C:)你的代码工作得很好,只要你在最后三行中删除0xFF后的分号。我会自己编辑它,但这是少于6个字符的更改。花了将近8年时间,但终于有人发现了语法错误。谢谢@moosmorals:)我很抱歉现在不是在我的linux机器上,但htons是标准库之一吗?根据标准c库的一部分,yeshtons几乎在任何地方都可用,但它不在ISO c中。如果您必须使用网络字节顺序以外的内容,那么您可以使用位运算符或根据它使用各种版本的java.nio.buffers它的手册页在POSIX.1中定义,所以它应该在几乎所有地方都可用。我似乎记得在Win32中使用过它,所以它也不仅仅在POSIX系统上。是否要评论一下您为什么投票否决我?因为即使我在哪里单独读取每个字节,发送的字节的尾端也不正确,所以我需要修改一个字节的垂直长度?这到底是什么?单词对尾数很敏感,单个字节不敏感。@hhafez这不是真的,字节没有尾数。我们需要关注的是,如果你逐字节读取,你,程序员负责将字节分配到正确的位置。这正是DataInputStream所做的是的,它只是把字节以一种大端的方式组合在一起。@WouterLievens:我遇到过一些I/O设备(例如实时时钟芯片)无论出于何种原因,它都以位反转格式发送数据;在从它们接收数据之后,有必要反转每个字节中的位。不过,我同意你的观点,字节的尾端通常不是一个问题,除非你必须处理特殊设计的硬件。他只能在他的协议使用相同的endianness。我修复了链接,并将其更改为指向Java 9,即当前版本。不过,所讨论的API是在Java 1.0中引入的。哦,当然有。二进制数学(&,|),但如果这样做,您仍然无法说出endianes是什么
 // Declare an array of 4 shorts to hold the four unsigned bytes
 short[] tempShort = new short[4];
 for (int b = 0; b < 4; b++) {
    tempShort[b] = (short)dIStream.readUnsignedByte();           
 }
 int curVal = convToInt(tempShort);

 // Pass an array of four shorts which convert from LSB first 
 public int convToInt(short[] sb)
 {
   int answer = sb[0];
   answer += sb[1] << 8;
   answer += sb[2] << 16;
   answer += sb[3] << 24;
   return answer;        
 }