Hey guys,
Just a quick question here:
What is the limit on decimal places that the engine executes? I am working on a couple of functionalities and several of them include physics’ constants. The thing is that some of these constants are minuscule (say for example the Gravitational Constant) and whenever I calculate for them, I get a 0.0 return value.
I’ve noticed throughout my working in Engine with Blueprints that after 7 decimal points, the number gets rounded to 0. However, constants like these are important for calculations that I’m doing as I am approaching it from a more realistic perspective.
I am doing these functionalities inside C++ and was wondering if C++ scripts are allowed to access more decimal places.
If not, how can I get around this? (Have them in their scientific notation as two separate values [one being the value, the other being e(n)] or what other options do I have)
The precision of floating-point numbers is variable. The larger the number, the smaller the decimal precision. However, even for numbers around 0 there is not nearly enough precision to do any sort of operations with the numbers you are talking about.
You can try doing all your calculations using doubles and then transfer the final calculated values to the Unreal engine which uses floats, but if the final values also require extremely high precision this won’t really work either. Instead you’ll need to do some scaling. What you’ll want to do is pick a reasonable fixed scale like x100 or x1000. All values being fed into the engine should use this scale. You can do your high precision calculations using doubles and then apply the scaling and map those values to unreal. If you need even more precision than double (which is certainly possible) then you may need to bring in a scientific math library which can do the low-level, super-high-precision math for you, then use the scaling trick when converting them to values that unreal can use.
Great answer, Brian.
I just want to add, in case it’s not already clear to everyone, that these limitations are not specific to Unreal Engine, C++, any operating system, or otherwise; rather, this is a challenge that is found throughout all of computer science.
Luckily for game development, though, I find that the precision limits of floats aren’t often a problem for achieving realism in physics simulations.
magfund, you mentioned losing precision in the editor after the 7th decimal position. At the 7th decimal position, you’re tuning values by the ten-millionths. Those are extremely tiny differences that are probably smaller than the threshold for your audience to even notice. That said, realism is almost certainly achievable with the precision that the editor is able to provide.
By the way, judging by your mention of the gravitational constant, I’m thinking you might be calculating orbital motions of planetary bodies, which, at realistic scales, ends up involving lots of extremely small compounding forces that can easily get rounded to zero by floating-point precision limits. If I guessed right, you’re going to have to get creative to work around those limitations, such as using the scaling trick that Brian recommends, and perhaps accepting some amount of loss of accuracy. The trouble is, solar systems at real-life scales are staggeringly large and yet involve very small moment-to-moment changes, which is a nasty combination. As Brian explained, floating points lose more decimal accuracy for larger numbers (such as the distances that separate planetary bodies), meaning some compromise may be required. Just a bit of warning from someone who’s encountered this challenge before.
Finally, if you’re not familiar with the concept of origin shifting, I recommend doing some googling to learn a bit about it. You may not need it for your game, but its existence in games is a consequence of dealing with the limitations of floating point precision.
Hope this helps!
Thank you both for the detailed notes and explanations! I will try to get around this. I’ll post a potential solution once I reach a reasonable workaround (hopefully without having to get into low-level libraries).
Also for anyone that could have this question in the future, the limitation is related to the fact that Blueprints support a Maximum of 32 Bits per set of data, so the limit is 32 Bit
If anyone’s curious & coming to this question later on (like me), here’s an academic paper on recursively sub-dividing a simulation into sectors & treating objects in each sector as having a local coordinate system (which at least helps with part of the issue)
Link: https://www.scitepress.org/Papers/2021/101945/101945.pdf