summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-06-09 12:50:33 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-06-09 12:50:33 +0000
commitdfad8317aa566efffb971455b42bfdecbaee5985 (patch)
tree47d6529f55d5ea1ea61f50d9179cba5964a4999b /src
parentdb671ffb8673c5088749663e64713d9b852ec1e5 (diff)
downloadopenttd-dfad8317aa566efffb971455b42bfdecbaee5985.tar.xz
(svn r25347) -Add: function for deterministic approximate division
Diffstat (limited to 'src')
-rw-r--r--src/core/math_func.cpp21
-rw-r--r--src/core/math_func.hpp1
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.