source: trunk/poppler/mypoppler/goo/FixedPoint.cc @ 515

Last change on this file since 515 was 515, checked in by Silvan Scherrer, 9 years ago

updated poppler to 0.20.3

File size: 2.7 KB
Line 
1//========================================================================
2//
3// FixedPoint.cc
4//
5// Fixed point type, with C++ operators.
6//
7// Copyright 2004 Glyph & Cog, LLC
8//
9//========================================================================
10
11#include <config.h>
12
13#if USE_FIXEDPOINT
14
15#ifdef USE_GCC_PRAGMAS
16#pragma implementation
17#endif
18
19#include "FixedPoint.h"
20
21#define ln2 ((FixedPoint)0.69314718)
22
23#define ln2 ((FixedPoint)0.69314718)
24
25FixedPoint FixedPoint::sqrt(FixedPoint x) {
26  FixedPoint y0, y1, z;
27
28  if (x.val <= 0) {
29    y1.val = 0;
30  } else {
31    y1.val = x.val == 1 ? 2 : x.val >> 1;
32    do {
33      y0.val = y1.val;
34      z = x / y0;
35      y1.val = (y0.val + z.val) >> 1;
36    } while (::abs(y0.val - y1.val) > 1);
37  }
38  return y1;
39}
40
41FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) {
42  FixedPoint t, t2, lnx0, lnx, z0, z;
43  int d, n, i;
44
45  if (y.val <= 0) {
46    z.val = 0;
47  } else {
48    // y * ln(x)
49    t = (x - 1) / (x + 1);
50    t2 = t * t;
51    d = 1;
52    lnx = 0;
53    do {
54      lnx0 = lnx;
55      lnx += t / d;
56      t *= t2;
57      d += 2;
58    } while (::abs(lnx.val - lnx0.val) > 2);
59    lnx.val <<= 1;
60    t = y * lnx;
61    // exp(y * ln(x))
62    n = floor(t / ln2);
63    t -= ln2 * n;
64    t2 = t;
65    d = 1;
66    i = 1;
67    z = 1;
68    do {
69      z0 = z;
70      z += t2 / d;
71      t2 *= t;
72      ++i;
73      d *= i;
74    } while (::abs(z.val - z0.val) > 2 && d < (1 << fixptShift));
75    if (n >= 0) {
76      z.val <<= n;
77    } else if (n < 0) {
78      z.val >>= -n;
79    }
80  }
81  return z;
82}
83
84int FixedPoint::mul(int x, int y) {
85  FixPtInt64 z;
86
87  z = ((FixPtInt64)x * y) >> fixptShift;
88  if (z > 0x7fffffffLL) {
89    return 0x7fffffff;
90  } else if (z < -0x80000000LL) {
91    return 0x80000000;
92  } else {
93    return (int)z;
94  }
95}
96
97int FixedPoint::div(int x, int y) {
98  FixPtInt64 z;
99
100  z = ((FixPtInt64)x << fixptShift) / y;
101  if (z > 0x7fffffffLL) {
102    return 0x7fffffff;
103  } else if (z < -0x80000000LL) {
104    return 0x80000000;
105  } else {
106    return (int)z;
107  }
108}
109
110GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) {
111  FixPtInt64 z;
112
113  z = ((FixPtInt64)x.val << fixptShift) / y.val;
114  if ((z == 0 && x != 0) ||
115      z >= ((FixPtInt64)1 << 31) || z < -((FixPtInt64)1 << 31)) {
116    return gFalse;
117  }
118  result->val = z;
119  return gTrue;
120}
121
122GBool FixedPoint::checkDet(FixedPoint m11, FixedPoint m12,
123                          FixedPoint m21, FixedPoint m22,
124                          FixedPoint epsilon) {
125  FixPtInt64 det, e;
126
127  det = (FixPtInt64)m11.val * (FixPtInt64)m22.val
128        - (FixPtInt64)m12.val * (FixPtInt64)m21.val;
129  e = (FixPtInt64)epsilon.val << fixptShift;
130  // NB: this comparison has to be >= not > because epsilon can be
131  // truncated to zero as a fixed point value.
132  return det >= e || det <= -e;
133}
134
135#endif // USE_FIXEDPOINT
Note: See TracBrowser for help on using the repository browser.