我正在尝试将java中的scientific double转换为decimal double。我从服务器(在C ++上编码)发送一个在X86(小端)机器上运行的值,我在使用htonl,ntohl方法进行转换之前将数据发送到客户端(在java上编码)。但现在,我必须发送此值而不像LE那样进行转换。转换是在客户端(java)端完成的。其他类型可以正确转换,但对于double,这不存在。当客户端收到double类型时,无法正确读取此值。这是我的双重转换的java代码。
protected int readInt(InputStream stream) throws IOException {
int i0 = read(stream);
int i1 = read(stream);
int i2 = read(stream);
int i3 = read(stream);
int i=(i0 << 24) + (i1 << 16) + (i2 << 8) + (i3 << 0);
return i;
}
protected double readDouble(InputStream stream) throws IOException {
int i0 = readInt(stream);
int i1 = readInt(stream);
return Double.longBitsToDouble(((long)i0 << 32) + (i1 & 0xffffffffL));
}
完成所有这些步骤后,如果我从服务器发送0.3,我得到了9.534475227E-315 谢谢和问候。
答案 0 :(得分:3)
听起来你正在从客户端读错值,但无论如何,NumberFormat是你的朋友:) http://java.sun.com/j2se/1.5.0/docs/api/index.html?java/text/NumberFormat.html
编辑:考虑到您发布的代码示例,我必须同意@trashgod您的转换代码存在缺陷。 Perhap DataInputStream可以提供帮助 - &gt; http://java.sun.com/javase/6/docs/api/java/io/DataInputStream.html
答案 1 :(得分:1)
答案 2 :(得分:1)
您使用术语“科学记数法”sorta表明您正在处理看起来像“3.0e-1”的文本数据。但我想我明白了。
似乎问题只是读取以非java字顺序编写的二进制数据。然而,为什么整数写成大端,但双打写的小端?你为什么这么奇怪地读书?你的编译器不抱怨'int'吗?它可能隐藏了一个问题。 (编辑:我的错误 - 我被困在64位的双倍)
每个人都可以看到数据的十六进制转储。字节是翻转的,还是单词?
也许这段代码会提供一些灵感。请原谅使用变量的'get-r-done'。
// convert CLI argument to double, write to file, and read back
// without args, default is "0.3"
// should try negative numbers!
import java.io.*;
public class BinaryFile {
public static void main(String[] args) {
String strFilePath = "WordFlippedDouble";
boolean WRITEOP = true;
double d, dd = 0.3;
long ddFlip;
if(args.length > 0) {
dd = Double.valueOf(args[0]);
}
System.out.println("Starting with " + dd + " looks like " +
Long.toHexString(Double.doubleToLongBits(dd)));
if(WRITEOP) {
ddFlip = Double.doubleToLongBits(dd);
ddFlip = (ddFlip<<32) | ((ddFlip>>32) & 0xFFFFFFFFL);
System.out.println("WRITE: (flipped) looks like " + Long.toHexString(ddFlip));
try {
FileOutputStream fout = new FileOutputStream(strFilePath);
DataOutputStream dout = new DataOutputStream(fout);
dout.writeLong(ddFlip);
dout.close();
} catch (Exception e) {
System.out.println("ERROR: " + e.getMessage());
}
}
if(false) return; // testing
try {
FileInputStream fin = new FileInputStream(strFilePath);
DataInputStream din = new DataInputStream(fin);
ddFlip = din.readLong();
d = Double.longBitsToDouble((ddFlip<<32) | ((ddFlip>>32) & 0xFFFFFFFFL));
System.out.println("READ: " + Long.toHexString(ddFlip) + " converts to " +
d + " DIFF: " + (dd-d));
din.close();
} catch(FileNotFoundException e) {
System.out.println("FileNotFoundException : " + e);
}
catch(IOException e) {
System.out.println("IOException : " + e);
}
}
}
答案 3 :(得分:1)
不要像那样翻滚自己的位。它在标准API中。请参阅java.nio.ByteBuffer
。
protected int readInt(InputStream stream) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE);
//buffer.order(ByteOrder.LITTLE_ENDIAN); // optional
stream.read(buffer.array());
return buffer.getInt(0);
}
protected double readDouble(InputStream stream) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(Double.SIZE / Byte.SIZE);
//buffer.order(ByteOrder.LITTLE_ENDIAN); // optional
stream.read(buffer.array());
return buffer.getDouble(0);
}
答案 4 :(得分:0)
如果您从服务器向客户端发送0.3并返回9.534475227E-315,那么您应该做的最后一件事就是将该值再次转换为0.3。 f-p术语中返回的值非常接近0,表示发送和返回过程中存在一些错误。
我对你的问题感到困惑,我不知道Java实现了一个Decimal类,但后来我的Java知识已经很老了。你或许是指BigDecimal吗?或者你正在转换浮点数的字符串格式,这将是一个完全不同的鱼?
答案 5 :(得分:0)
我解决了我的问题并感谢大家的帮助。非常感激。所以这是解决方案。
protected double readDouble(InputStream stream) throws IOException {
return Double.longBitsToDouble(((long) read(stream) & 0xff)
| ((long) (read(stream) & 0xff) << 8)
| ((long) (read(stream) & 0xff) << 16)
| ((long) (read(stream) & 0xff) << 24)
| ((long) (read(stream) & 0xff) << 32)
| ((long) (read(stream) & 0xff) << 40)
| ((long) (read(stream) & 0xff) << 48)
| ((long) (read(stream) & 0xff) << 56)); }
当我以小端格式从服务器发送数据时,我可以使用java中的代码将传入的小端格式化值转换为大端格式化值。