Floating point accuracy in Java not as accurate as C/C++?

Not double floats, just single floats(32 bit).

I’ve previously read that java has greater FP accuracy than C*(’*’ = wildmark for C, C++ and C#).
This might be what I’m seeing, however I would like clarification if this indeed is the case.

My test was done using LWJGL’s math class.
All the test invovled was using vector3f’s in order to do an orthogonal projection from one vector onto the same vector without the Y-COORD.

IE: vec(x, y, z) is projected onto vec(x, 0, z).

I’ve written my own vector class in C++ for my assignment, it uses floats and does the EXACT same operations as LWJGL’s math class does because there really is only one method of working with vectors.

Anyway, the reason I projected (x, y, z) onto (x, 0, z) is to map the point onto a 3D sphere.
The sphere’s equation must satisfy the following condition:
xx + yy + z*z = 1.

NOTE:
After doing all my computation and making sure the intermediate calculations do the EXACT same thing in both libraries(my own and LWJGL’s) I’ve come up with 2 results.

C++: 1.000000.
Java: 0.9999995.

So is Java more accurate or less accurate?
Do I need to floor Java’s result after every normalised vector operation?

Excuse me, but how would a projection onto a plane help with projecting onto a sphere?

I don’t quite understand what’s going on.

What makes you think the C++ and Java results are actually different? In particular how did you print the result? If you were to print the Java result to only 6 decimal places it would very likely produce the same result as you printed from C++.

Java’s default conversion from float (and double) to string has the unusual property of containing sufficient digits to allow the original float value to be reconstructed exactly. In other words

float x;
float z = Float.parseFloat(String.valueOf(x));
boolean result = z == x;

For any value of x, Java requires the result to be true. The default conversion of most other languages results in a standard number of decimal places or, for larger values, a fixed number of significant figures.

To compare your results in C++ and Java more easily, I suggest you subtract 1 from the value and print the resulting ‘error’ term. Then the interesting information from the point of view of comparing accuracy will be in the first few digits.

A second factor which may apply is that Java requires arithmetic on float values to be carried out with exactly float precision; netiher more nor less is permitted. Other languages may treat float just as a storage size and perform the computation to any convenient accuracy. Java’s approach has the advantage that a developer won’t be fooled into thinking his code works merely because his machine happens to compute (a badly conditioned expression) with unusual accuracy. So with Java we don’t get code which works when run on an Intel machine where compiler chooses to use the 80 bit temporary real for internal values, and then fails to work on a PowerPC where ordinary double precision is used. It used to be common (at least for mathematicians) to have to tune numeric code very carefully for particular compiler and processor combinations. With Java we just target the Java specification and all conforming JVM should then produce exactly the same result (with some minor caveats for exponent overflow/underflow).

In any case why are you worrying about an apparent difference of only 5e-7 ?

Thanks.
I initially used “print” to output the result.
Strangely enough it’s now giving me the right result.

I went into Eclipse’s debugger to re-check everything and it is now giving me 1.0f exactly.
Very strange issue I had.
It’s cleared up now.

The reason I’m worried about error is because when I do interpolation between quaternions and vectors and other stuff I need absolute precision.
I’m actually thinking about writing a shader to do my calcs and then return the final result in order to keep maximum precision, then again video cards usually have less precision than general prupose CPUs.

You can make 32-bit float tetxures.

But as I mentioned in onther thread, the communication between the vRAM and RAM is so slow it’s just not worth it. It only works out if you can reduce the vRAM<>RAM I/O to an absolute minimum. Say: hundreds or operations on each texel.

[quote=“Riven,post:6,topic:25096”]
I wanted to ask you this in that thread: Did you try using PBO? It’s not a general solution of course, but certain algorithms could benefit from asynchronous readbacks.

Well, async alone won’t help much, as you’d have to wait for the pixels anyway.

But the PBO spec says it’s a DMA transfer (zero copy) which might speed things up, but I’ll have to measure that.

[quote=“Riven,post:8,topic:25096”]
My point was that, depending on the algorithm, you don’t necessarily have to wait:

  1. You run the shader at one frame and read the results at the next one (like occlusion query).

  2. You do the double buffer trick, processing half the result while reading the other half (last example in the PBO spec).

The problem is the calculation takes about 1000 shorter than the I/O…

So when you take your approach it will be 2 times faster, yes, but what is two times faster than extremely slow worth?

Anyway, so much for the theory, I’ll make a benchmark, that DMA thingy might give a significant boost all by itself.

Not true! If x == Float.NaN, result will be false.

Argh, because of course Float.NaN != Float.NaN
The round trip through String does recover the identical value even for NaN, it is just the test which is tricky.
The test should read
Float.toIntBits(z) == Float.toIntBits(x)

Sorry for being so nitpicky. :wink:

I couldn’t resist!

Why do you guys get on each other’s nerves?
“Argh” isn’t exactly a friendly manner in which one would respond with.

PS: This is not an attempt by me to get flamed.

‘Argh’ is not directed at anyone else, usually, when you read it on the forums. It’s the equivalent of slapping your forehead in real life when you realize you’ve made a mistake. Or, as Homer would say, “Doh!”.

That explains it.
I thought it meant that he was sick of explaining things and implied the other person is an idiot.
That’s usually the case in some other forums I visit anyway.

Sorry for the misinterpretation.

Exactly right. The peculiar characteristic that NaN isn’t equal to itself was something I ought to have remembered. At the time I was concentrating on the fact that the String conversion should round trip the values exactly (including the NaN case) and forgot that the equality test is tricky.

I noticed none of that getting-on-nervmanship you speak of. :slight_smile:

My bad.
Not many forums are friendly and my interpretations are usually wrong.

Yeah, K.I.L.E.R is a trouble maker. Let’s get him! :stuck_out_tongue:

(sorry couldn’t resist)