1/* This file is part of the KDE project
2 Copyright 2007 Tomas Mecir <mecirt@gmail.com>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; only
7 version 2 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "Number.h"
21
22#ifdef CALLIGRA_SHEETS_HIGH_PRECISION_SUPPORT
23
24#include <math.h>
25
26using namespace Calligra::Sheets;
27
28class Number::Private : public QSharedData
29{
30public:
31 Private() {
32 type = Number::Float;
33 f = 0;
34 }
35
36 Private(const Private &o) : QSharedData(o), type(o.type) {
37 switch (type) {
38 case Number::Float:
39 f = o.f;
40 break;
41 }
42 }
43
44 Number::Type type;
45
46 union {
47 long double f;
48 };
49
50 // static empty data to be shared
51 static Private* null() {
52 if (!s_null) s_null = new Private; return s_null;
53 }
54
55private:
56 void operator=(const Number::Private& o);
57 static Private *s_null;
58};
59
60Number::Private *Number::Private::s_null = 0;
61
62// constructors
63
64Number::Number()
65 : d(Private::null())
66{
67 d->type = Number::Float;
68 d->f = 0.0;
69}
70
71Number::Number(int num)
72 : d(Private::null())
73{
74 d->type = Number::Float;
75 d->f = (long double) num;
76}
77
78Number::Number(long double num)
79 : d(Private::null())
80{
81 d->type = Number::Float;
82 d->f = num;
83}
84
85Number::Number(const Number& n)
86 : d(n.d)
87{
88}
89
90// this destructor must exist here for the header file to compile properly,
91// otherwise QSharedDataPointer destructor screams at us
92Number::~Number()
93{
94}
95
96// set/get
97Number& Number::operator= (const Number & n)
98{
99 d = n.d;
100 return *this;
101}
102
103
104long double Number::asFloat() const
105{
106 return d->f;
107}
108
109// basic operations
110Number Number::operator+ (const Number &n) const
111{
112 return Number(d->f + n.d->f);
113}
114
115Number Number::operator- (const Number &n) const
116{
117 return Number(d->f - n.d->f);
118}
119
120Number Number::operator*(const Number &n) const
121{
122 return Number(d->f * n.d->f);
123}
124
125Number Number::operator/ (const Number &n) const
126{
127 return Number(d->f / n.d->f);
128}
129
130void Number::operator+= (const Number & n)
131{
132 d->f += n.d->f;
133}
134
135void Number::operator-= (const Number & n)
136{
137 d->f -= n.d->f;
138}
139
140void Number::operator*= (const Number & n)
141{
142 d->f *= n.d->f;
143}
144
145void Number::operator/= (const Number & n)
146{
147 d->f /= n.d->f;
148}
149
150Number Number::operator- () const
151{
152 return -(d->f);
153}
154
155// comparison
156bool Number::operator<= (const Number &n) const
157{
158 return (d->f <= n.d->f);
159}
160
161bool Number::operator< (const Number &n) const
162{
163 return (d->f < n.d->f);
164}
165
166bool Number::operator== (const Number &n) const
167{
168 return (d->f == n.d->f);
169}
170
171Number Number::mod(const Number &n) const
172{
173 return Number(::fmod(d->f, n.d->f));
174}
175
176Number Number::abs() const
177{
178 return Number(::fabs(d->f));
179}
180
181Number Number::neg() const
182{
183 return Number(-1 * d->f);
184}
185
186Number Number::pow(const Number &exp) const
187{
188 return Number(::pow(d->f, exp.d->f));
189}
190
191Number Number::log(Number base) const
192{
193 long double logbase = ::log10(base.d->f);
194 return Number(::log10(d->f) / logbase);
195}
196
197Number Number::ln() const
198{
199 return Number(::log(d->f));
200}
201
202Number Number::exp() const
203{
204 return Number(::exp(d->f));
205}
206
207// goniometric functions
208Number Number::sin() const
209{
210 return Number(::sin(d->f));
211}
212
213Number Number::cos() const
214{
215 return Number(::cos(d->f));
216}
217
218Number Number::tg() const
219{
220 return Number(::tan(d->f));
221}
222
223Number Number::cotg() const
224{
225 return Number(1 / ::tan(d->f));
226}
227
228Number Number::asin() const
229{
230 return Number(::asin(d->f));
231}
232
233Number Number::acos() const
234{
235 return Number(::acos(d->f));
236}
237
238Number Number::atg() const
239{
240 return Number(::atan(d->f));
241}
242
243Number Number::atan2(const Number &y, const Number &x)
244{
245 return Number(::atan2(y.d->f, x.d->f));
246}
247
248
249// hyperbolic functions
250Number Number::sinh() const
251{
252 return Number(::sinh(d->f));
253}
254
255Number Number::cosh() const
256{
257 return Number(::cosh(d->f));
258}
259
260Number Number::tgh() const
261{
262 return Number(::tanh(d->f));
263}
264
265Number Number::asinh() const
266{
267 return Number(::asinh(d->f));
268}
269
270Number Number::acosh() const
271{
272 return Number(::acosh(d->f));
273}
274
275Number Number::atgh() const
276{
277 return Number(::atanh(d->f));
278}
279
280// *** EXTERNAL FUNCTIONS ***
281
282namespace Calligra
283{
284namespace Sheets
285{
286
287long double numToDouble(Number n)
288{
289 return n.asFloat();
290}
291
292// external operators, so that we can do things like 4+a without having to create temporary objects
293// not provided for complex numbers, as we won't be using them often like that
294Number operator+ (long double n1, const Number &n2)
295{
296 return n2 + n1;
297}
298Number operator- (long double n1, const Number &n2)
299{
300 return (n2 - n1).neg();
301}
302Number operator*(long double n1, const Number &n2)
303{
304 return n2 * n1;
305}
306Number operator/ (long double n1, const Number &n2)
307{
308 return Number(n1) / n2; /* TODO optimize perhaps */
309}
310bool operator<= (long double n1, const Number &n2)
311{
312 return (n2 >= n1);
313}
314bool operator< (long double n1, const Number &n2)
315{
316 return (n2 > n1);
317}
318bool operator== (long double n1, const Number &n2)
319{
320 return (n2 == n1);
321}
322bool operator!= (long double n1, const Number &n2)
323{
324 return (n2 != n1);
325}
326bool operator>= (long double n1, const Number &n2)
327{
328 return (n2 <= n1);
329}
330bool operator> (long double n1, const Number &n2)
331{
332 return (n2 < n1);
333}
334
335// external versions of the functions
336Number fmod(const Number &n1, const Number &n2)
337{
338 return n1.mod(n2);
339}
340Number fabs(const Number &n)
341{
342 return n.abs();
343}
344Number abs(const Number &n)
345{
346 return n.abs();
347}
348Number neg(const Number &n)
349{
350 return n.neg();
351}
352Number pow(const Number &n, const Number &exp)
353{
354 return n.pow(exp);
355}
356Number sqrt(const Number &n)
357{
358 return n.pow(0.5);
359}
360Number log(const Number &n, Number base)
361{
362 return n.log(base);
363}
364Number ln(const Number &n)
365{
366 return n.ln();
367}
368Number log(const Number &n)
369{
370 return n.ln();
371}
372Number log10(const Number &n)
373{
374 return n.log(10);
375}
376Number exp(const Number &n)
377{
378 return n.exp();
379}
380Number sin(const Number &n)
381{
382 return n.sin();
383}
384Number cos(const Number &n)
385{
386 return n.cos();
387}
388Number tg(const Number &n)
389{
390 return n.tg();
391}
392Number cotg(const Number &n)
393{
394 return n.cotg();
395}
396Number asin(const Number &n)
397{
398 return n.asin();
399}
400Number acos(const Number &n)
401{
402 return n.acos();
403}
404Number atg(const Number &n)
405{
406 return n.atg();
407}
408Number atan2(const Number &y, const Number &x)
409{
410 return Number::atan2(y, x);
411}
412Number sinh(const Number &n)
413{
414 return n.sinh();
415}
416Number cosh(const Number &n)
417{
418 return n.cosh();
419}
420Number tgh(const Number &n)
421{
422 return n.tgh();
423}
424Number asinh(const Number &n)
425{
426 return n.asinh();
427}
428Number acosh(const Number &n)
429{
430 return n.acosh();
431}
432Number atgh(const Number &n)
433{
434 return n.atgh();
435}
436
437} // namespace Sheets
438} // namespace Calligra
439
440#endif // CALLIGRA_SHEETS_HIGH_PRECISION_SUPPORT
441