File indexing completed on 2024-04-28 16:21:25

0001 /* This file is part of the KDE project
0002    Copyright 2007 Tomas Mecir <mecirt@gmail.com>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; only
0007    version 2 of the License.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "Number.h"
0021 
0022 #ifdef CALLIGRA_SHEETS_HIGH_PRECISION_SUPPORT
0023 
0024 #include <math.h>
0025 
0026 using namespace Calligra::Sheets;
0027 
0028 class Q_DECL_HIDDEN Number::Private : public QSharedData
0029 {
0030 public:
0031     Private() {
0032         type = Number::Float;
0033         f = 0;
0034     }
0035 
0036     Private(const Private &o) : QSharedData(o), type(o.type) {
0037         switch (type) {
0038         case Number::Float:
0039             f = o.f;
0040             break;
0041         }
0042     }
0043 
0044     Number::Type type;
0045 
0046     union {
0047         long double f;
0048     };
0049 
0050     // static empty data to be shared
0051     static Private* null() {
0052         if (!s_null) s_null = new Private; return s_null;
0053     }
0054 
0055 private:
0056     void operator=(const Number::Private& o);
0057     static Private *s_null;
0058 };
0059 
0060 Number::Private *Number::Private::s_null = 0;
0061 
0062 // constructors
0063 
0064 Number::Number()
0065         : d(Private::null())
0066 {
0067     d->type = Number::Float;
0068     d->f = 0.0;
0069 }
0070 
0071 Number::Number(int num)
0072         : d(Private::null())
0073 {
0074     d->type = Number::Float;
0075     d->f = (long double) num;
0076 }
0077 
0078 Number::Number(long double num)
0079         : d(Private::null())
0080 {
0081     d->type = Number::Float;
0082     d->f = num;
0083 }
0084 
0085 Number::Number(const Number& n)
0086         : d(n.d)
0087 {
0088 }
0089 
0090 // this destructor must exist here for the header file to compile properly,
0091 // otherwise QSharedDataPointer destructor screams at us
0092 Number::~Number()
0093 {
0094 }
0095 
0096 // set/get
0097 Number& Number::operator= (const Number & n)
0098 {
0099     d = n.d;
0100     return *this;
0101 }
0102 
0103 
0104 long double Number::asFloat() const
0105 {
0106     return d->f;
0107 }
0108 
0109 // basic operations
0110 Number Number::operator+ (const Number &n) const
0111 {
0112     return Number(d->f + n.d->f);
0113 }
0114 
0115 Number Number::operator- (const Number &n) const
0116 {
0117     return Number(d->f - n.d->f);
0118 }
0119 
0120 Number Number::operator*(const Number &n) const
0121 {
0122     return Number(d->f * n.d->f);
0123 }
0124 
0125 Number Number::operator/ (const Number &n) const
0126 {
0127     return Number(d->f / n.d->f);
0128 }
0129 
0130 void Number::operator+= (const Number & n)
0131 {
0132     d->f += n.d->f;
0133 }
0134 
0135 void Number::operator-= (const Number & n)
0136 {
0137     d->f -= n.d->f;
0138 }
0139 
0140 void Number::operator*= (const Number & n)
0141 {
0142     d->f *= n.d->f;
0143 }
0144 
0145 void Number::operator/= (const Number & n)
0146 {
0147     d->f /= n.d->f;
0148 }
0149 
0150 Number Number::operator- () const
0151 {
0152     return -(d->f);
0153 }
0154 
0155 // comparison
0156 bool Number::operator<= (const Number &n) const
0157 {
0158     return (d->f <= n.d->f);
0159 }
0160 
0161 bool Number::operator< (const Number &n) const
0162 {
0163     return (d->f < n.d->f);
0164 }
0165 
0166 bool Number::operator== (const Number &n) const
0167 {
0168     return (d->f == n.d->f);
0169 }
0170 
0171 Number Number::mod(const Number &n) const
0172 {
0173     return Number(::fmod(d->f, n.d->f));
0174 }
0175 
0176 Number Number::abs() const
0177 {
0178     return Number(::fabs(d->f));
0179 }
0180 
0181 Number Number::neg() const
0182 {
0183     return Number(-1 * d->f);
0184 }
0185 
0186 Number Number::pow(const Number &exp) const
0187 {
0188     return Number(::pow(d->f, exp.d->f));
0189 }
0190 
0191 Number Number::log(Number base) const
0192 {
0193     long double logbase = ::log10(base.d->f);
0194     return Number(::log10(d->f) / logbase);
0195 }
0196 
0197 Number Number::ln() const
0198 {
0199     return Number(::log(d->f));
0200 }
0201 
0202 Number Number::exp() const
0203 {
0204     return Number(::exp(d->f));
0205 }
0206 
0207 // goniometric functions
0208 Number Number::sin() const
0209 {
0210     return Number(::sin(d->f));
0211 }
0212 
0213 Number Number::cos() const
0214 {
0215     return Number(::cos(d->f));
0216 }
0217 
0218 Number Number::tg() const
0219 {
0220     return Number(::tan(d->f));
0221 }
0222 
0223 Number Number::cotg() const
0224 {
0225     return Number(1 / ::tan(d->f));
0226 }
0227 
0228 Number Number::asin() const
0229 {
0230     return Number(::asin(d->f));
0231 }
0232 
0233 Number Number::acos() const
0234 {
0235     return Number(::acos(d->f));
0236 }
0237 
0238 Number Number::atg() const
0239 {
0240     return Number(::atan(d->f));
0241 }
0242 
0243 Number Number::atan2(const Number &y, const Number &x)
0244 {
0245     return Number(::atan2(y.d->f, x.d->f));
0246 }
0247 
0248 
0249 // hyperbolic functions
0250 Number Number::sinh() const
0251 {
0252     return Number(::sinh(d->f));
0253 }
0254 
0255 Number Number::cosh() const
0256 {
0257     return Number(::cosh(d->f));
0258 }
0259 
0260 Number Number::tgh() const
0261 {
0262     return Number(::tanh(d->f));
0263 }
0264 
0265 Number Number::asinh() const
0266 {
0267     return Number(::asinh(d->f));
0268 }
0269 
0270 Number Number::acosh() const
0271 {
0272     return Number(::acosh(d->f));
0273 }
0274 
0275 Number Number::atgh() const
0276 {
0277     return Number(::atanh(d->f));
0278 }
0279 
0280 // *** EXTERNAL FUNCTIONS ***
0281 
0282 namespace Calligra
0283 {
0284 namespace Sheets
0285 {
0286 
0287 long double numToDouble(Number n)
0288 {
0289     return n.asFloat();
0290 }
0291 
0292 // external operators, so that we can do things like 4+a without having to create temporary objects
0293 // not provided for complex numbers, as we won't be using them often like that
0294 Number operator+ (long double n1, const Number &n2)
0295 {
0296     return n2 + n1;
0297 }
0298 Number operator- (long double n1, const Number &n2)
0299 {
0300     return (n2 - n1).neg();
0301 }
0302 Number operator*(long double n1, const Number &n2)
0303 {
0304     return n2 * n1;
0305 }
0306 Number operator/ (long double n1, const Number &n2)
0307 {
0308     return Number(n1) / n2; /* TODO optimize perhaps */
0309 }
0310 bool operator<= (long double n1, const Number &n2)
0311 {
0312     return (n2 >= n1);
0313 }
0314 bool operator< (long double n1, const Number &n2)
0315 {
0316     return (n2 > n1);
0317 }
0318 bool operator== (long double n1, const Number &n2)
0319 {
0320     return (n2 == n1);
0321 }
0322 bool operator!= (long double n1, const Number &n2)
0323 {
0324     return (n2 != n1);
0325 }
0326 bool operator>= (long double n1, const Number &n2)
0327 {
0328     return (n2 <= n1);
0329 }
0330 bool operator> (long double n1, const Number &n2)
0331 {
0332     return (n2 < n1);
0333 }
0334 
0335 // external versions of the functions
0336 Number fmod(const Number &n1, const Number &n2)
0337 {
0338     return n1.mod(n2);
0339 }
0340 Number fabs(const Number &n)
0341 {
0342     return n.abs();
0343 }
0344 Number abs(const Number &n)
0345 {
0346     return n.abs();
0347 }
0348 Number neg(const Number &n)
0349 {
0350     return n.neg();
0351 }
0352 Number pow(const Number &n, const Number &exp)
0353 {
0354     return n.pow(exp);
0355 }
0356 Number sqrt(const Number &n)
0357 {
0358     return n.pow(0.5);
0359 }
0360 Number log(const Number &n, Number base)
0361 {
0362     return n.log(base);
0363 }
0364 Number ln(const Number &n)
0365 {
0366     return n.ln();
0367 }
0368 Number log(const Number &n)
0369 {
0370     return n.ln();
0371 }
0372 Number log10(const Number &n)
0373 {
0374     return n.log(10);
0375 }
0376 Number exp(const Number &n)
0377 {
0378     return n.exp();
0379 }
0380 Number sin(const Number &n)
0381 {
0382     return n.sin();
0383 }
0384 Number cos(const Number &n)
0385 {
0386     return n.cos();
0387 }
0388 Number tg(const Number &n)
0389 {
0390     return n.tg();
0391 }
0392 Number cotg(const Number &n)
0393 {
0394     return n.cotg();
0395 }
0396 Number asin(const Number &n)
0397 {
0398     return n.asin();
0399 }
0400 Number acos(const Number &n)
0401 {
0402     return n.acos();
0403 }
0404 Number atg(const Number &n)
0405 {
0406     return n.atg();
0407 }
0408 Number atan2(const Number &y, const Number &x)
0409 {
0410     return Number::atan2(y, x);
0411 }
0412 Number sinh(const Number &n)
0413 {
0414     return n.sinh();
0415 }
0416 Number cosh(const Number &n)
0417 {
0418     return n.cosh();
0419 }
0420 Number tgh(const Number &n)
0421 {
0422     return n.tgh();
0423 }
0424 Number asinh(const Number &n)
0425 {
0426     return n.asinh();
0427 }
0428 Number acosh(const Number &n)
0429 {
0430     return n.acosh();
0431 }
0432 Number atgh(const Number &n)
0433 {
0434     return n.atgh();
0435 }
0436 
0437 } // namespace Sheets
0438 } // namespace Calligra
0439 
0440 #endif // CALLIGRA_SHEETS_HIGH_PRECISION_SUPPORT