#1990 closed defect (fixed)
[PATCH] OOS due to inconsistent Math.pow
Reported by: | scythetwirler | Owned by: | ben |
---|---|---|---|
Priority: | Release Blocker | Milestone: | Alpha 14 |
Component: | Core engine | Keywords: | patch |
Cc: | Jonathan Waller | Patch: |
Description (last modified by )
OOS error between a computer running Ubuntu 12.04.2 and Ubuntu 13.04.
scythetwirler - Ubuntu 12.04.2 (64-bit)
Heiko - Ubuntu 13.04 (32-bit)
Map: Oasis 9
OOS is triggered when female citizen builds next on the same structure as a citizen soldier, adding a bonus.
Attachments (6)
Change History (20)
by , 11 years ago
Attachment: | Heiko commands.txt.zip added |
---|
by , 11 years ago
Attachment: | Heiko oos_dump.txt.zip added |
---|
by , 11 years ago
Attachment: | scythetwirler_commands.txt.tar.gz added |
---|
by , 11 years ago
Attachment: | scythetwirler_oos_dump.txt.tar.gz added |
---|
comment:1 by , 11 years ago
Description: | modified (diff) |
---|
comment:2 by , 11 years ago
Description: | modified (diff) |
---|
comment:3 by , 11 years ago
Summary: | OOS during normal gameplay in multiplayer → OOS due to inconsistent Math.pow |
---|
comment:4 by , 11 years ago
Description: | modified (diff) |
---|
comment:5 by , 11 years ago
I've implemented a separate Pow function.
It's only around 5 decimal digits precise, but it's numerically stable. I only use the four basic operation (add, substract, multiply and divide). However, I don't know if those are perfectly deterministic across platforms (I certainly hope so).
scythewirler, can I ask you to try it out? Just replace the contents of data/mod/public/globalscripts/Math.js file with this code: http://pastebin.com/EDPeLKQy
You will see a lot of warnings when powers are calculated. Those warnings will also be in the console. So you can already compare from the first calculations if something will be wrong or not. If it works, and you want to get rid of the warnings, just remove line 153.
When it works, we can look into making it more precise, or changing some algorithms by better ones.
comment:6 by , 11 years ago
That fixed it for me so far for Win64-Ubuntu32! I'll test Ubuntu64 with Ubuntu32 later.
comment:7 by , 11 years ago
Keywords: | patch review added |
---|---|
Summary: | OOS due to inconsistent Math.pow → [PATCH] OOS due to inconsistent Math.pow |
Cleaned up the code a bit, and removed the warnings.
comment:9 by , 11 years ago
Cc: | added |
---|
Thanks for working on this. Our implementations should properly handle the special cases in the spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf (page 160-5)
I don't know if 5 digits is enough precision, how hard is it to improve that?
by , 11 years ago
comment:10 by , 11 years ago
Thanks for the ECMA spec.
I improved the precision, and now, the overall worst precision (according to my calculations) is around 17 decimal digits for the pow function (similar numbers for other functions).
I also implemented those ECMA script special values (NaN, Infinity ...) and I think they are correct now. But it would be great if someone can confirm my thoughts.
by , 11 years ago
Attachment: | test_Math.js.patch added |
---|
comment:11 by , 11 years ago
They look good to me. I wrote some tests (see test_Math.js.patch), all the special cases passed and results for a few other tests I added were consistent between an Athlon XP and a Core i7-2600K. Do you have any more tests to suggest?
Some interesting differences with your implementations in extreme cases:
Math.log(1.7e308) // => 709.7268368932282 with SM Math Math.log(1.7e308) // => 709.0895657128241 with yours Math.exp(Math.log(1.7e308)) // => 1.6999999999999472e+308 with SM Math Math.exp(Math.log(1.7e308)) // => 8.988465674311613e+307 with yours
It doesn't really matter other than for comparing precision and possibly not worth worrying about.
comment:12 by , 11 years ago
I think that is because of the rounding issues in JS itself. Normally the log should be about 16 decimal digits precise. But if the rounding error accumulates through the loop, I can't help that a lot. I thought by using divisions and multiplications by 2, it wouldn't round, but apparently not.
comment:14 by , 11 years ago
Keywords: | review removed |
---|
Same as the last report:
both times it was
buildMultiplier
, which quantumstate pointed out is the result of an expression usingMath.pow
(known to produce different results on different platforms, see Bugzilla).