- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 Java 编写一个程序来输入一个文件,供另一个用 C++ 编写的程序使用。因此,该文件必须是 float 的小端二进制文件。
我使用了许多不同类型的方法来进行这种字节序转换,包括 Apache Commons I/O、Geosoft 实用程序(与 apache 完全相同......)和 ByteBuffer。
总而言之,我必须取一堆 float 并以二进制小端方式显示它们。这个过程大部分时间都有效。但是,在某些情况下,在将 float 识别为 NaN 的字节序转换中似乎存在一些精度错误。结果,当我读取刚刚写入的二进制文件时,大约有 1% 的时间显示的不是特定的 float ,而是 6.055E-41 之类的数字。我在网上搜索过类似的问题。
另一个人诊断出错误包含在 float 到 Int Bits 和 Int Bits 到 float 之间的转换中(在 Apache 和 Geosoft Utilities 中找到)。
推荐的解决方案是将文件直接转换为 int 位,而不是进行这种循环处理。但是,就我而言,直接转换为整数会使我失去对我需要编写的原始 float 的精度。推荐的方案是,供大家引用:
"By reading a float using the readFloat() routine of DataInputStream, converting it to bits using Float.floatToIntBits(), swapping the Integer, then converting it back to float using Float.intBitsToFloat() causes a precision error in certain cases resulting in junk being returned.
The solution is to write a new set of routines that read the bits from the bytestream directly into integers, then perform the byte swapping and converting it back to a float."
这是问题的一个例子......
将这一系列的 float 写入二进制文件并读回时,预期的结果是这样的:
1.50411975 -1.974895 1.0301249 -0.43540177 0.8161005 0.38000694 0.43332508
但是,我看到了这个:
6.9055E-41 -1.974895 1.0301249 -0.43540177 0.8161005 0.38000694 0.43332508
我正在粘贴我的代码。此版本专门使用字节缓冲区实现。您能告诉我哪里出了问题以及我该如何解决吗?
public int writeBinaryFile( ArrayList<P> p) throws FileNotFoundException, IOException
{
int c = 0;
for (int i = 0; i < p(); i++)
{
ArrayList<Float> cube = new ArrayList<Float>();
ArrayList<Float> dir = p.get(i).getDirection();
ArrayList<Float> pos = p.get(i).getPosition();
Float angle = (float) p.get(i).getAngle();
Float id = (float) p.get(i).getPEvents().get(0).getid();
ArrayList<Float> things = new ArrayList<Float>();
boolean truism = true;
if (dir.get(1) > 0 ) {
/*byte [] byte2 = this.float2ByteArray(id);
float f = ByteBuffer.wrap(byte2).order(ByteOrder.LITTLE_ENDIAN ).getFloat();
dos.writeFloat(f);*/
for (int j = 0; j < pos.size(); j++) {
byte [] bytes = this.float2ByteArray(pos.get(j));
float d = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN ).getFloat();
cube.add(d);
}
for (int j = 0; j < dir.size(); j++) {
byte [] bytes = this.float2ByteArray(dir.get(j));
float d = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN ).getFloat();
cube.add(d);
}
byte [] bytes = this.float2ByteArray(angle);
float d = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN ).getFloat();
cube.add(d);
if (this.checkCube(cube)) {this.writeCube(cube); c++; }
}
}
return c;
}
public byte [] float2ByteArray(float value)
{
return ByteBuffer.allocate(4).putFloat(value).array();
}
这是我的备用交换机制:
public static float swap (float value)
{
int intValue = Float.floatToRawIntBits (value);
intValue = swap (intValue);
return Float.intBitsToFloat (intValue);
}
public static int swap (int value)
{
int b1 = (value >> 0) & 0xff;
int b2 = (value >> 8) & 0xff;
int b3 = (value >> 16) & 0xff;
int b4 = (value >> 24) & 0xff;
return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
}
我尝试使用直接使用整数的东西。这是我的特殊交换器:
public static float specialswap (float value)
{
int intValue = Float.floatToRawIntBits (value);
return Integer.reverseBytes(Integer.parseInt(Integer.toBinaryString(intValue)));
已解决:感谢 Louis Wasserman,找到了我的问题的答案:
dataOutputStream.writeInt(Integer.reverseBytes(Float.floatToRawIntBits(float))).
最佳答案
您是从输入流中获取数字,还是将它们写入输出流?目前尚不清楚您要做什么。如果您从 InputStream
读取它们,您应该只执行一行 Float.intBitsToFloat(Integer.reverseBytes(dataInputStream.readInt()))
。如果您将它们写入 OutputStream
,您应该只执行一行 dataOutputStream.writeInt(Integer.reverseBytes(Float.floatToRawIntBits(float)))
.其他一切都只是在原地打转。
关于java - Little Endian 到 Big Endian 精度误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17683429/
小端与大端 大字节序 = 0x31014950 小字节序 = 0x50490131 但是使用这个方法 inline unsigned int endian_swap(unsigned int& x)
当我通过套接字将一个整数变量从一个进程发送到另一个进程,然后在接收端打印值时,不使用 ntohl/htonl,该值仍然相同,那么除了初始化之外,我还需要在哪里使用这些函数套接字结构。我了解小/大端。但
我只是想问一下我的方法从小端到大端的转换是否正确,只是为了确定我是否理解其中的区别。 我有一个数字存储在小端,这里是数字的二进制和十六进制表示: 0001 0010 0011 0100 0101 0
Big Endian 和 Little Endian 字节顺序有什么区别? 这两个似乎都与 Unicode 和 UTF16 有关。我们到底在哪里使用它? 最佳答案 Big-Endian (BE)/Li
我遇到了以下问题: int i[20] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; int *p
char S[6] = "18243"; 以下字符串在大端系统和小端系统中如何表示? 最佳答案 char 类型保存单个字节。因此,该类型不涉及字节序。 在您的示例中,您有一个数组。数组元素一个接一个地
我正在用 Java 编写一个程序来输入一个文件,供另一个用 C++ 编写的程序使用。因此,该文件必须是 float 的小端二进制文件。 我使用了许多不同类型的方法来进行这种字节序转换,包括 Apach
我正在尝试制作一个Java程序,它接收大端字节序的二进制字符串,如下所示:“11001100111111110001010011000000”。程序应该输出相同的字符串,但转换为 Little End
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 4 年前。 Improve t
我有一个定义为的结构: struct record { int age; char name[12]; int department; }; 如果我从二进制文件中读取数据并且数据包含
在我的代码中有一个结构存在填充问题。我修复了它们,我的代码在小端机器上运行良好。这种结构是否有可能导致大端机器出现问题?? 最佳答案 您需要牢记以下几点: 无论何时进行数据通信,通信协议(protoc
我目前的任务是剖析包含 P2P 消息的 tcpdump 数据,我在获取和写入 x86 机器上的文件的片段数据时遇到了问题。我怀疑我写入文件的字节有一个简单的字节顺序问题。 我有一个字节列表,其中包含一
我怎样才能将小字节序二进制文件转换成大字节序二进制文件。我有一个用 C 编写的二进制二进制文件,我正在用 Java 使用 DataInputStream 读取这个文件,它以大端格式读取。我还查看了 B
全部, 我一直在网上练习编码问题。目前我正在处理一个问题陈述 Problems,我们需要转换 Big Endian little endian。但是考虑到给出的示例,我无法记下步骤: 1234567
你好,我在小端和大端有一个小问题,我知道这个问题已经问过 n 次了,但我无法弄清楚以下几点 让 int i=10 在堆栈部分以二进制形式存储为 00000000 00000000 00000000 0
我们需要支持 3 种硬件平台 - Windows(小端)和 Linux Embedded(大端和小端)。我们的数据流取决于它使用的机器,数据需要分解成位域。 我想写一个宏(如果可能的话)来抽象掉细节。
我在询问如何判断数组中的一个元素何时完成,而另一个元素何时以字节序架构开始。 我有 2 个数组,其中 long 的大小是 8,大小为 char是 1long x[2] = {0x012345,0xFE
我正在编写解析器代码以从二进制文件中读取所有数据。顺便说一句,二进制文件是大端的。当我读取文件的二进制头时,我通过这种方法将其读入 Structure: 结构: struct BinaryHeader
我很好奇这个函数是否会决定字节顺序。 测试是一个位掩码,如果整数 someInt 存储在小端中,则该位掩码等于 1。 在位掩码中,0x1000 会被转换以匹配机器的字节序样式还是“常量”? #incl
我正在使用 MIPS (QtSpim) 将 32 位字从 Big Endian 转换为 Little Endian。我在下面显示的内容经过检查且正确无误。但是,我想知道还有哪些其他方式可以让我进行转换
我是一名优秀的程序员,十分优秀!