🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Floating Point Variance

Started by
2 comments, last by Galshin 23 years, 4 months ago
I am making a 3d space RTS, and I am doing my networking fully synchronized. I made the assumption that if each computer simulates 2 games, and are both given all the same variables, that the outcomes would be identical. I am having problems! I have a method that does a bunch of floating point math, and it is returning different numbers on different computers. But the #''s are only off by like 10-6 or 10-7, but that error carried over and over is enough to throw things out of wack. All it does is Mul''s, Div''s, adds and subs... nothing fancy, but the results are coming out different. (off by like 1 bit every time) Here is the line of code that is returning different results: FLOAT rtn = ((h0 * (1.0f-xoff) + (h1 * xoff)) * (1.0f-yoff) + (h2 * (1.0f-xoff) + (h3 * xoff)) * yoff)*zscale; If I cout all the variables, h0,h1,h2,h3,xoff,yoff,zscale... There are identical on each computer... but nonetheless, they are returning different results? Anyone have any ideas... FYI, I rounded the result off to the thousands place, and everything is working fine... But I don''t feel like I should have to do that.. .they should produce the same #. Help Please!
Advertisement
No, rounding is a perfectly valid, and sadly, the only effective solution. In really speed-critical places I recommend you use fixed point maths if possible, as it saves you the time for rounding.

You should use fixed point for network transmission anyway, as it''s a more portable solution (you don''t have to worry about different architectures etc...). Note that even if you use fixed point for net transmission, you have to do the rounding! Otherwise the rounding errors will accumulate locally, until they''re big enough to become visible in the fixed-point you''re using for networking.

cu,
Prefect

---
Sanity is the trademark of a weak mind.
Widelands - laid back, free software strategy
There is an IEEE standard for floating point math, and most modern chips implement it. That said, the real world is full of hardware bugs, software emulators, and some processors that simply don''t conform.

If you want to use floating point, you might consider using the same floating point implementation on all platforms -- there are public domain FP implementations out there. Here''s one:

http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html

Otherwise, you might consider using fixed point if you can tolerate the coarseness.

Matt Slot / Bitwise Operator / Ambrosia Software, Inc.
Your problem really surprises me... what processors are you testing on?

Anyway, first suggestion: Make sure your input variables are really identical. I don''t know if "cout" really prints a float''s entire precision... you could do this instead:

float val;cout << (*(long*)&val); 


You might also look into the different FPU settings... I know there is a "low precision" setting, for example (which speeds up divisions and square roots). Perhaps it would help to explicitly configure the FPUs identically on both machines.

If I were you, I would go to fixed-point only as a last resort... its a pain in the ass and not really any faster on modern processors.

Also, to quickly round float''s, you could probably set up a bit mask to zero out the last one or two bits in the mantissa, but that would be totally platform-specific, which would probably make matters worse

This topic is closed to new replies.

Advertisement