You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
f32 division/multiplication and .tan() platform behavior #75786
I know floats aren't exactly known for their precision and i might be missing something.
But i'm seeing some odd platform dependent behavior when i combine a f32 float division with .tan()
// mac
1.22221994400024414062500000000000
0.61110997200012207031250000000000
0.70057231187820434570312500000000
// linux
1.22221994400024414062500000000000
0.61110997200012207031250000000000
0.70057231187820434570312500000000
// windows
1.22221994400024414062500000000000
0.61110997200012207031250000000000
0.70057231187820434570312500000000
All the outputs are the same as i guess is expected.
// mac & linux
1.22222197055816650390625000000000
0.61111098527908325195312500000000
0.70057380199432373046875000000000
// windows
1.22222197055816650390625000000000
0.61111098527908325195312500000000
0.70057386159896850585937500000000
Now windows suddenly shows a different output on the last line.
I have testet this on my windows 10 pc, linux laptop (mint) and a github actions matrix of ubuntu, windows, mac, nightly, beta and stable.
Ah yea i see what you mean.
I was also messing around with f64 to see if i could make it act weird, but was without luck.
Didn't think to compare the values.
// mac windows
1.22222197055816650390625000000000
2.44444394111633300781250000000000
-0.83742588758468627929687500000000
// linux
1.22222197055816650390625000000000
2.44444394111633300781250000000000
-0.83742594718933105468750000000000
This is probably just because of the tan -- multiplication and division are required to be good to ½ULP, but IIRC the trig functions only need to be good to 1ULP, which means it's expected that there can be differences.
If you throw that last example into float toy, you'll see
0xBF56618B -0.8374259
0xBF56618C -0.83742594
^
A difference of 1ULP, as expected.
There are plenty of resources about floating point determinism related to real-time strategy games, see for example the things referenced in https://gamedev.stackexchange.com/a/174374
So I think there isn't actually anything to fix here, as unfortunate as that is. This is just why games tend to use their own trig approximations for anything that needs to be portable, rather than the platform ones.
Indeed, multiplication and division should be consistent across platforms. Can you confirm that this is the case here? If yes, we should remove their mention from the issue title.
tan, on the other hand, doesn't have a precise spec -- so basically, this is expected behavior. I guess if we want to improve the situation here, we'd want to have a pure-Rust fast and precise implementation of tan (and friends) and make rustc use that instead of the system library. :D
Closing this for now as it doesn't focus on the actual problem without division/multiplication.
Might open a new issue if I ever have the time and motivation.
Activity
cuviper commentedon Aug 21, 2020
This is similar to #73420 -- your Windows result looks like it has computed via
f64.I tried this on the playground (Linux):
Blisto91 commentedon Aug 21, 2020
Ah yea i see what you mean.
I was also messing around with
f64to see if i could make it act weird, but was without luck.Didn't think to compare the values.
Blisto91 commentedon Aug 21, 2020
Adding some more stuff i just found.
With multiplication ubuntu is the odd one out.
[-]f32 division and .tan() platform behavior [/-][+]f32 division/multiplication and .tan() platform behavior [/+]scottmcm commentedon Aug 24, 2020
This is probably just because of the
tan-- multiplication and division are required to be good to ½ULP, but IIRC the trig functions only need to be good to 1ULP, which means it's expected that there can be differences.If you throw that last example into float toy, you'll see
A difference of 1ULP, as expected.
There are plenty of resources about floating point determinism related to real-time strategy games, see for example the things referenced in https://gamedev.stackexchange.com/a/174374
So I think there isn't actually anything to fix here, as unfortunate as that is. This is just why games tend to use their own trig approximations for anything that needs to be portable, rather than the platform ones.
Blisto91 commentedon Aug 24, 2020
@scottmcm Thanks for the explanation! And thank you for the links.
Gonna bookmark them. :)
I was told that dimforge rapier is gonna have cross platform determinism so i was wondering.
But as you said they probably have their own implementations. 👍
If you say this is expected behavior then feel free to close it. I don't have enough knowledge on the subject to be able to chime in.
Edit:
Also gonna read up on posits because they sound interesting.
RalfJung commentedon Aug 30, 2020
Indeed, multiplication and division should be consistent across platforms. Can you confirm that this is the case here? If yes, we should remove their mention from the issue title.
tan, on the other hand, doesn't have a precise spec -- so basically, this is expected behavior. I guess if we want to improve the situation here, we'd want to have a pure-Rust fast and precise implementation oftan(and friends) and make rustc use that instead of the system library. :DBlisto91 commentedon Oct 1, 2020
Sorry for not keeping this up to date. Sleep has not been agreeing with me lately.
Will try and update this without the division/multiplication here soon when i have time
Blisto91 commentedon Jul 20, 2021
Closing this for now as it doesn't focus on the actual problem without division/multiplication.
Might open a new issue if I ever have the time and motivation.