summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-3.02/goo/FixedPoint.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-3.02/goo/FixedPoint.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-3.02/goo/FixedPoint.cc118
1 files changed, 118 insertions, 0 deletions
diff --git a/Build/source/libs/xpdf/xpdf-3.02/goo/FixedPoint.cc b/Build/source/libs/xpdf/xpdf-3.02/goo/FixedPoint.cc
new file mode 100644
index 00000000000..47c2834a34b
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-3.02/goo/FixedPoint.cc
@@ -0,0 +1,118 @@
+//========================================================================
+//
+// FixedPoint.cc
+//
+// Fixed point type, with C++ operators.
+//
+// Copyright 2004 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#if USE_FIXEDPOINT
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "FixedPoint.h"
+
+#define ln2 ((FixedPoint)0.69314718)
+
+FixedPoint FixedPoint::sqrt(FixedPoint x) {
+ FixedPoint y0, y1, z;
+
+ if (x.val <= 0) {
+ y1.val = 0;
+ } else {
+ y1.val = x.val == 1 ? 2 : x.val >> 1;
+ do {
+ y0.val = y1.val;
+ z = x / y0;
+ y1.val = (y0.val + z.val) >> 1;
+ } while (::abs(y0.val - y1.val) > 1);
+ }
+ return y1;
+}
+
+FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) {
+ FixedPoint t, t2, lnx0, lnx, z0, z;
+ int d, n, i;
+
+ if (y.val <= 0) {
+ z.val = 0;
+ } else {
+ // y * ln(x)
+ t = (x - 1) / (x + 1);
+ t2 = t * t;
+ d = 1;
+ lnx = 0;
+ do {
+ lnx0 = lnx;
+ lnx += t / d;
+ t *= t2;
+ d += 2;
+ } while (::abs(lnx.val - lnx0.val) > 2);
+ lnx.val <<= 1;
+ t = y * lnx;
+ // exp(y * ln(x))
+ n = floor(t / ln2);
+ t -= ln2 * n;
+ t2 = t;
+ d = 1;
+ i = 1;
+ z = 1;
+ do {
+ z0 = z;
+ z += t2 / d;
+ t2 *= t;
+ ++i;
+ d *= i;
+ } while (::abs(z.val - z0.val) > 2 && d < (1 << fixptShift));
+ if (n >= 0) {
+ z.val <<= n;
+ } else if (n < 0) {
+ z.val >>= -n;
+ }
+ }
+ return z;
+}
+
+int FixedPoint::mul(int x, int y) {
+#if 1 //~tmp
+ return ((FixPtInt64)x * y) >> fixptShift;
+#else
+ int ah0, ah, bh, al, bl;
+ ah0 = x & fixptMaskH;
+ ah = x >> fixptShift;
+ al = x - ah0;
+ bh = y >> fixptShift;
+ bl = y - (bh << fixptShift);
+ return ah0 * bh + ah * bl + al * bh + ((al * bl) >> fixptShift);
+#endif
+}
+
+int FixedPoint::div(int x, int y) {
+#if 1 //~tmp
+ return ((FixPtInt64)x << fixptShift) / y;
+#else
+#endif
+}
+
+GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) {
+#if 1 //~tmp
+ FixPtInt64 z;
+
+ z = ((FixPtInt64)x.val << fixptShift) / y.val;
+ if ((z == 0 && x != 0) ||
+ z >= ((FixPtInt64)1 << 31) || z < -((FixPtInt64)1 << 31)) {
+ return gFalse;
+ }
+ result->val = z;
+ return gTrue;
+#else
+#endif
+}
+
+#endif // USE_FIXEDPOINT