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

Last change on this file since 461 was 250, checked in by Eugene Romanenko, 13 years ago

PDF plugin: poppler library updated to version 0.8.3

File size: 2.2 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#if 1 //~tmp
86  return ((FixPtInt64)x * y) >> fixptShift;
87#else
88  int ah0, ah, bh, al, bl;
89  ah0 = x & fixptMaskH;
90  ah = x >> fixptShift;
91  al = x - ah0;
92  bh = y >> fixptShift;
93  bl = y - (bh << fixptShift);
94  return ah0 * bh + ah * bl + al * bh + ((al * bl) >> fixptShift);
95#endif
96}
97
98int FixedPoint::div(int x, int y) {
99#if 1 //~tmp
100  return ((FixPtInt64)x << fixptShift) / y;
101#else
102#endif
103}
104
105GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) {
106#if 1 //~tmp
107  FixPtInt64 z;
108
109  z = ((FixPtInt64)x.val << fixptShift) / y.val;
110  if ((z == 0 && x != 0) ||
111      z >= ((FixPtInt64)1 << 31) || z < -((FixPtInt64)1 << 31)) {
112    return gFalse;
113  }
114  result->val = z;
115  return gTrue;
116#else
117#endif
118}
119
120#endif // USE_FIXEDPOINT
Note: See TracBrowser for help on using the repository browser.