diff options
author | fonsinchen <fonsinchen@openttd.org> | 2013-06-09 12:50:33 +0000 |
---|---|---|
committer | fonsinchen <fonsinchen@openttd.org> | 2013-06-09 12:50:33 +0000 |
commit | dfad8317aa566efffb971455b42bfdecbaee5985 (patch) | |
tree | 47d6529f55d5ea1ea61f50d9179cba5964a4999b /src | |
parent | db671ffb8673c5088749663e64713d9b852ec1e5 (diff) | |
download | openttd-dfad8317aa566efffb971455b42bfdecbaee5985.tar.xz |
(svn r25347) -Add: function for deterministic approximate division
Diffstat (limited to 'src')
-rw-r--r-- | src/core/math_func.cpp | 21 | ||||
-rw-r--r-- | src/core/math_func.hpp | 1 |
2 files changed, 22 insertions, 0 deletions
diff --git a/src/core/math_func.cpp b/src/core/math_func.cpp index 2b8ca3309..8c136c0bb 100644 --- a/src/core/math_func.cpp +++ b/src/core/math_func.cpp @@ -48,6 +48,27 @@ int GreatestCommonDivisor(int a, int b) } /** + * Deterministic approximate division. + * Cancels out division errors stemming from the integer nature of the division over multiple runs. + * @param a Dividend. + * @param b Divisor. + * @return a/b or (a/b)+1. + */ +int DivideApprox(int a, int b) +{ + int random_like = ((a + b) * (a - b)) % b; + + int remainder = a % b; + + int ret = a / b; + if (abs(random_like) < abs(remainder)) { + ret += ((a < 0) ^ (b < 0)) ? -1 : 1; + } + + return ret; +} + +/** * Compute the integer square root. * @param num Radicand. * @return Rounded integer square root. diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index b613d1e6a..fd4110231 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.hpp @@ -317,6 +317,7 @@ static inline uint ToPercent16(uint i) int LeastCommonMultiple(int a, int b); int GreatestCommonDivisor(int a, int b); +int DivideApprox(int a, int b); /** * Computes ceil(a / b) for non-negative a and b. |