0

I'm reading file, written with C floats in java.

myFileRead(bptr, 4, n_row, stream);
for (int i=0;i<n_row;i++)
    ptr.set(i,Float.intBitsToFloat(ByteBuffer.wrap(bptr,i*4,4)
    .order(ByteOrder.LITTLE_ENDIAN).getInt()));

C output:

input[j]    -0.0922103971   float
wr[j]        0.00706708990  float

Java output:

input.get(j) = {Float@602} "-0.0922104"
wr.get(j)    = {Float@603} "0.00706709"

Java also gives me this:

input.get(j).doubleValue() = -0.09221039712429047
wr.get(j).doubleValue() = 0.0070670899003744125

Then I need to multiply these two values and it doesn't match in two ways.

(input.get(j) * wr.get(j)) = -6.5165915E-4
(input.get(j).doubleValue() * wr.get(j).doubleValue()) = -6.516591662265869E-4

C output:

input[j]*wr[j]  -0.000651659153 float

Then error accumulates and after for() cycle

for(j = 0; j < input_size; j++)
  z += input.get(j) * wr.get(j);
output.set(i, z);

output is:

 C:    -2.99740553
 Java: -2.7654826641082764

Seems like java Float too short (how does it have double value then?) and Double too long for that. How can I make Java output match C output?

Nalmelune
  • 78
  • 2
  • 10
  • Don't use floating-point calculation, use `BigDecimal` for precise calculus. – Tunaki Sep 20 '15 at 20:03
  • Please show us the complete code. Looks like rounding issues to me. – fuz Sep 20 '15 at 20:13
  • *"written with C floats"* as @Tunaki, don't use `float` in C, use `double` or `long double` if available. – Weather Vane Sep 20 '15 at 20:18
  • @FUZxxl did a little edit – Nalmelune Sep 20 '15 at 20:18
  • What platform, for both of them? Maybe one of them is using the dreaded x87 environment but not the other? – harold Sep 20 '15 at 20:23
  • @harold how sure if that's what you mean, but this code is being executed on 64 bit machine – Nalmelune Sep 20 '15 at 20:31
  • @chux can't use double since this code is already optimized to work, I'm just this translating code. – Nalmelune Sep 20 '15 at 20:33
  • Please provide a *complete* self-contained example. As of now, even after your edit, your question is impossible to answer. A self-contained example is one I can compile and run on my machine to observe the problem you have. – fuz Sep 20 '15 at 20:41
  • @WeatherVane If OP uses floats in Java, he should use floats in C, too. This could explain the different results, but OP fails to provide all the relevant code, so I can't help him. – fuz Sep 20 '15 at 20:42
  • 1
    @Nalmelune that is not enough information though, for java it matters whether it's run with a 64bit JVM, for C it matters whether it's compiled as 64bit (and how, because you can usually control x87 vs sse), that is not necessarily the case just because the OS is 64bit. You might try `strictfp` for the Java version. – harold Sep 20 '15 at 20:42
  • Are you looking to get the _same_ answer or the best answer each platform can provide? AFAIK, both answers are incorrect. Suggest, temporarily use `long double`, and find the "correct" answer and then work each code desperately to get closer to that target. If needed `for(j = 0; j < input_size; j++) z += input.get(j) * wr.get(j);` can be improved using various techniques as that appear to be where the error accumulation occurs. – chux - Reinstate Monica Sep 20 '15 at 21:02
  • A `float` in C is not as precisely defined as it is in Java; it may be either of a 16bit or 32bit, base2, IEEE floating point number. In Java it will _always_ be a 32bit base2 IEEE floating point. What is more, arithmetic operands on floats in C is... Well... Not as well defined as they are in Java either. Try and use `strictfp` in Java and see if the results match. Further than that, as requested by @FUZxxl, please write an SSCCE, and provide the architecture, compiler etc used for your C program (and the code too). – fge Sep 20 '15 at 21:12
  • @fge Most common C implementations have a 32 bit IEEE floating point number for float and a 64 bit IEEE floating point number for double and guarantee IEEE semantics (possibly with higher intermediate accuracy, if the 8087 FPU is used in 80 bit mode) for basic floating point operations, just like Java. Yes, in a theoretic sense this is not precisely defined, but in a practical sense you can get pretty close. – fuz Sep 20 '15 at 21:57
  • 1
    @fge Note: 16-bit `float` does not meet C requirements of at least 6 decimal digits and range of `pow(+/-37)`. I estimate at least 27 bits are needed. – chux - Reinstate Monica Sep 20 '15 at 22:01
  • @harold strictfp seems to be working. thank you! – Nalmelune Sep 21 '15 at 17:39

0 Answers0