Sounds like a well-found bug.

Could you open a Jira issue with this information? Partly so it
doesn't get lost, but also so that we can have a nice definition of
the issues in the next release.

http://issues.apache.org/jira/browse/IO

Thanks,

Hen

On 5/17/06, Warren Freitag <[EMAIL PROTECTED]> wrote:
Hi,

I've been using the EndianUtils class in Commons IO to convert an input
file containing little-endian doubles in binary format. However I've
come across a few situations where the function swapDouble() returns the
wrong value, owing to the fact that the current implementation does the
endian swapping by first converting the input value to long using
java.lang.Double.doubleToLongBits(). However, as the Java docs claim,
this means of converting double to long doesn't properly handle cases
where the conversion to long results in "NaN". Unfortunately, I don't
have handy a specific example, but I can assure the failure rate appears
to be about 1 in 10,000 for my input file of >2million numbers. In the
failure cases, I get "NaN" as the result from swapDouble().

The solution appears to be a simple one: change EndianUtils.java to use
doubleToRawLongBits() instead. Once I did this, my failure rate went to
0. The function doubleToRawLongBits() does a better job of preserving
NaN values, according to the JavaDoc
(http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Double.html#doubleToRawLongBits(double)).

I would like to check in my (very simple) change, but I'm unfamiliar
with the dev process for Commons so I felt I should share my findings
with the mailing list first.

One other thing (related, but maybe off-topic):
I'm reading my little-endian doubles from a binary file using the
RandomAccessFile class, but I've found that the following methods
produce different results in a few (<2%) cases:

RandomAccessFile file = new RandomAccessFile(...);

// Case 1: read double from file, do endian conversion using my change
to EndianUtils
file.seek(X);
double d1 = EndianUtils.swapDouble(file.readDouble());

// Case 2: read long, do endian conversion, then convert to double
file.seek(X);
double d2 = Double.longBitsToDouble(EndianUtils.swapLong(file.readLong()));

In the vast majority of cases, d1 == d2, but sometimes the precision
gets messed up. I'm talking very miniscule amounts (e.g.
d1=2942300.30053693 d2=2942300.3005359764) where digits below 10^-5 may
differ. Of course, the d1 case is less efficient, because
file.readDouble() actually reads in the value as a long, then converts
to double (if I'm not mistaken); finally, swapDouble() converts again to
long, does the endian conversion, then converts back to double. The d2
case skips the redundant long-to-double conversion and is thus faster --
and, I assume, more precise. Has anybody else encountered loss of
precision converting back and forth between double and long?

Thanks for hearing me out, and I do appreciate any feedback! Keep up the
great work, all!
-Warren

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to