• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

kcalc

  • sources
  • kde-4.12
  • kdeutils
  • kcalc
  • knumber
knumber_float.cpp
Go to the documentation of this file.
1 /*
2 Copyright (C) 2001 - 2013 Evan Teran
3  evan.teran@gmail.com
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <config-kcalc.h>
20 #include "knumber_integer.h"
21 #include "knumber_float.h"
22 #include "knumber_fraction.h"
23 #include "knumber_error.h"
24 #include <QScopedArrayPointer>
25 #include <QDebug>
26 #include <math.h>
27 
28 #ifdef _MSC_VER
29 double log2(double x) { return log(x) / log(2); }
30 double exp2(double x) { return exp(x * log(2)); }
31 double exp10(double x) { return exp(x * log(10)); }
32 #endif
33 
34 // NOTE: these assume IEEE floats..
35 #ifndef isinf
36 #define isinf(x) ((x) != 0.0 && (x) + (x) == (x))
37 #endif
38 
39 #ifndef isnan
40 #define isnan(x) ((x) != (x))
41 #endif
42 
43 namespace detail {
44 
45 #ifdef KNUMBER_USE_MPFR
46 const mpfr_rnd_t knumber_float::rounding_mode = MPFR_RNDN;
47 const mpfr_prec_t knumber_float::precision = 1024;
48 #endif
49 
50 template <double F(double)>
51 knumber_base *knumber_float::execute_libc_func(double x) {
52  const double r = F(x);
53  if(isnan(r)) {
54  knumber_error *e = new knumber_error(knumber_error::ERROR_UNDEFINED);
55  delete this;
56  return e;
57  } else if(isinf(r)) {
58  knumber_error *e = new knumber_error(knumber_error::ERROR_POS_INFINITY);
59  delete this;
60  return e;
61  } else {
62  mpf_set_d(mpf_, r);
63  return this;
64  }
65 }
66 
67 template <double F(double, double)>
68 knumber_base *knumber_float::execute_libc_func(double x, double y) {
69  const double r = F(x, y);
70  if(isnan(r)) {
71  knumber_error *e = new knumber_error(knumber_error::ERROR_UNDEFINED);
72  delete this;
73  return e;
74  } else if(isinf(r)) {
75  knumber_error *e = new knumber_error(knumber_error::ERROR_POS_INFINITY);
76  delete this;
77  return e;
78  } else {
79  mpf_set_d(mpf_, r);
80  return this;
81  }
82 }
83 
84 //------------------------------------------------------------------------------
85 // Name:
86 //------------------------------------------------------------------------------
87 knumber_float::knumber_float(const QString &s) {
88 
89  mpf_init(mpf_);
90  mpf_set_str(mpf_, s.toAscii(), 10);
91 }
92 
93 //------------------------------------------------------------------------------
94 // Name:
95 //------------------------------------------------------------------------------
96 knumber_float::knumber_float(double value) {
97 
98  Q_ASSERT(!isinf(value));
99  Q_ASSERT(!isnan(value));
100 
101  mpf_init_set_d(mpf_, value);
102 }
103 
104 #ifdef HAVE_LONG_DOUBLE
105 //------------------------------------------------------------------------------
106 // Name:
107 //------------------------------------------------------------------------------
108 knumber_float::knumber_float(long double value) {
109 
110  Q_ASSERT(!isinf(value));
111  Q_ASSERT(!isnan(value));
112 
113  mpf_init_set_d(mpf_, value);
114 }
115 #endif
116 
117 //------------------------------------------------------------------------------
118 // Name:
119 //------------------------------------------------------------------------------
120 knumber_float::knumber_float(mpf_t mpf) {
121 
122  mpf_init(mpf_);
123  mpf_set(mpf_, mpf);
124 }
125 
126 //------------------------------------------------------------------------------
127 // Name:
128 //------------------------------------------------------------------------------
129 knumber_float::knumber_float(const knumber_float *value) {
130 
131  mpf_init_set(mpf_, value->mpf_);
132 }
133 
134 //------------------------------------------------------------------------------
135 // Name:
136 //------------------------------------------------------------------------------
137 knumber_float::knumber_float(const knumber_integer *value) {
138 
139  mpf_init(mpf_);
140  mpf_set_z(mpf_, value->mpz_);
141 }
142 
143 //------------------------------------------------------------------------------
144 // Name:
145 //------------------------------------------------------------------------------
146 knumber_float::knumber_float(const knumber_fraction *value) {
147 
148  mpf_init(mpf_);
149  mpf_set_q(mpf_, value->mpq_);
150 }
151 
152 //------------------------------------------------------------------------------
153 // Name:
154 //------------------------------------------------------------------------------
155 knumber_base *knumber_float::clone() {
156 
157  return new knumber_float(this);
158 }
159 
160 //------------------------------------------------------------------------------
161 // Name:
162 //------------------------------------------------------------------------------
163 knumber_float::~knumber_float() {
164 
165  mpf_clear(mpf_);
166 }
167 
168 //------------------------------------------------------------------------------
169 // Name:
170 //------------------------------------------------------------------------------
171 knumber_base *knumber_float::add(knumber_base *rhs) {
172 
173  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
174  knumber_float f(p);
175  return add(&f);
176  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
177  mpf_add(mpf_, mpf_, p->mpf_);
178  return this;
179  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
180  knumber_float f(p);
181  return add(&f);
182  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
183  knumber_error *e = new knumber_error(p);
184  delete this;
185  return e;
186  }
187 
188  Q_ASSERT(0);
189  return 0;
190 }
191 
192 //------------------------------------------------------------------------------
193 // Name:
194 //------------------------------------------------------------------------------
195 knumber_base *knumber_float::sub(knumber_base *rhs) {
196 
197  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
198  knumber_float f(p);
199  return sub(&f);
200  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
201  mpf_sub(mpf_, mpf_, p->mpf_);
202  return this;
203  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
204  knumber_float f(p);
205  return sub(&f);
206  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
207  knumber_error *e = new knumber_error(p);
208  delete this;
209  return e->neg();
210  }
211 
212  Q_ASSERT(0);
213  return 0;
214 }
215 
216 //------------------------------------------------------------------------------
217 // Name:
218 //------------------------------------------------------------------------------
219 knumber_base *knumber_float::mul(knumber_base *rhs) {
220 
221  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
222  knumber_float f(p);
223  return mul(&f);
224  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
225  mpf_mul(mpf_, mpf_, p->mpf_);
226  return this;
227  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
228  knumber_float f(p);
229  return mul(&f);
230  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
231  if(is_zero()) {
232  delete this;
233  return new knumber_error(knumber_error::ERROR_UNDEFINED);
234  }
235 
236  if(sign() < 0) {
237  delete this;
238  knumber_error *e = new knumber_error(p);
239  return e->neg();
240  } else {
241  delete this;
242  return new knumber_error(p);
243  }
244  }
245 
246  Q_ASSERT(0);
247  return 0;
248 }
249 
250 //------------------------------------------------------------------------------
251 // Name:
252 //------------------------------------------------------------------------------
253 knumber_base *knumber_float::div(knumber_base *rhs) {
254 
255  if(rhs->is_zero()) {
256  if(sign() < 0) {
257  delete this;
258  return new knumber_error(knumber_error::ERROR_NEG_INFINITY);
259  } else {
260  delete this;
261  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
262  }
263  }
264 
265  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
266  knumber_float f(p);
267  return div(&f);
268  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
269  mpf_div(mpf_, mpf_, p->mpf_);
270  return this;
271  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
272  knumber_float f(p);
273  return div(&f);
274  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
275  if(p->sign() > 0 || p->sign() < 0) {
276  delete this;
277  return new knumber_integer(0);
278  }
279 
280  delete this;
281  return new knumber_error(p);
282  }
283 
284  Q_ASSERT(0);
285  return 0;
286 }
287 
288 //------------------------------------------------------------------------------
289 // Name:
290 //------------------------------------------------------------------------------
291 knumber_base *knumber_float::mod(knumber_base *rhs) {
292 
293  Q_UNUSED(rhs);
294 
295  if(rhs->is_zero()) {
296  delete this;
297  return new knumber_error(knumber_error::ERROR_UNDEFINED);
298  }
299 
300  delete this;
301  return new knumber_integer(0);
302 }
303 
304 //------------------------------------------------------------------------------
305 // Name:
306 //------------------------------------------------------------------------------
307 knumber_base *knumber_float::bitwise_and(knumber_base *rhs) {
308 
309  Q_UNUSED(rhs);
310  delete this;
311  return new knumber_integer(0);
312 }
313 
314 //------------------------------------------------------------------------------
315 // Name:
316 //------------------------------------------------------------------------------
317 knumber_base *knumber_float::bitwise_xor(knumber_base *rhs) {
318 
319  Q_UNUSED(rhs);
320  delete this;
321  return new knumber_integer(0);
322 }
323 
324 //------------------------------------------------------------------------------
325 // Name:
326 //------------------------------------------------------------------------------
327 knumber_base *knumber_float::bitwise_or(knumber_base *rhs) {
328 
329  Q_UNUSED(rhs);
330  delete this;
331  return new knumber_integer(0);
332 }
333 
334 //------------------------------------------------------------------------------
335 // Name:
336 //------------------------------------------------------------------------------
337 knumber_base *knumber_float::bitwise_shift(knumber_base *rhs) {
338 
339  Q_UNUSED(rhs);
340  delete this;
341  return new knumber_integer(0);
342 }
343 
344 //------------------------------------------------------------------------------
345 // Name:
346 //------------------------------------------------------------------------------
347 knumber_base *knumber_float::neg() {
348 
349  mpf_neg(mpf_, mpf_);
350  return this;
351 }
352 
353 //------------------------------------------------------------------------------
354 // Name:
355 //------------------------------------------------------------------------------
356 knumber_base *knumber_float::cmp() {
357 
358  delete this;
359  return new knumber_error(knumber_error::ERROR_UNDEFINED);
360 }
361 
362 //------------------------------------------------------------------------------
363 // Name:
364 //------------------------------------------------------------------------------
365 knumber_base *knumber_float::abs() {
366 
367  mpf_abs(mpf_, mpf_);
368  return this;
369 }
370 
371 //------------------------------------------------------------------------------
372 // Name:
373 //------------------------------------------------------------------------------
374 knumber_base *knumber_float::sqrt() {
375 
376  if(sign() < 0) {
377  delete this;
378  return new knumber_error(knumber_error::ERROR_UNDEFINED);
379  }
380 
381 #ifdef KNUMBER_USE_MPFR
382  mpfr_t mpfr;
383  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
384  mpfr_sqrt(mpfr, mpfr, rounding_mode);
385  mpfr_get_f(mpf_, mpfr, rounding_mode);
386  mpfr_clear(mpfr);
387 #else
388  mpf_sqrt(mpf_, mpf_);
389 #endif
390  return this;
391 }
392 
393 //------------------------------------------------------------------------------
394 // Name:
395 //------------------------------------------------------------------------------
396 knumber_base *knumber_float::cbrt() {
397 
398 #ifdef KNUMBER_USE_MPFR
399  mpfr_t mpfr;
400  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
401  mpfr_cbrt(mpfr, mpfr, rounding_mode);
402  mpfr_get_f(mpf_, mpfr, rounding_mode);
403  mpfr_clear(mpfr);
404 #else
405  const double x = mpf_get_d(mpf_);
406  if(isinf(x)) {
407  delete this;
408  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
409  } else {
410 #ifdef Q_CC_MSVC
411  return execute_libc_func< ::pow>(x, 1.0 / 3.0);
412 #else
413  return execute_libc_func< ::cbrt>(x);
414 #endif
415  }
416 #endif
417  return this;
418 }
419 
420 //------------------------------------------------------------------------------
421 // Name:
422 //------------------------------------------------------------------------------
423 knumber_base *knumber_float::factorial() {
424 
425  if(sign() < 0) {
426  delete this;
427  return new knumber_error(knumber_error::ERROR_UNDEFINED);
428  }
429 
430  knumber_integer *i = new knumber_integer(this);
431  delete this;
432  return i->factorial();
433 }
434 
435 //------------------------------------------------------------------------------
436 // Name:
437 //------------------------------------------------------------------------------
438 knumber_base *knumber_float::sin() {
439 
440 #ifdef KNUMBER_USE_MPFR
441  mpfr_t mpfr;
442  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
443  mpfr_sin(mpfr, mpfr, rounding_mode);
444  mpfr_get_f(mpf_, mpfr, rounding_mode);
445  mpfr_clear(mpfr);
446  return this;
447 #else
448  const double x = mpf_get_d(mpf_);
449  if(isinf(x)) {
450  delete this;
451  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
452  } else {
453  return execute_libc_func< ::sin>(x);
454  }
455 #endif
456 
457 }
458 
459 //------------------------------------------------------------------------------
460 // Name:
461 //------------------------------------------------------------------------------
462 knumber_base *knumber_float::cos() {
463 
464 #ifdef KNUMBER_USE_MPFR
465  mpfr_t mpfr;
466  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
467  mpfr_cos(mpfr, mpfr, rounding_mode);
468  mpfr_get_f(mpf_, mpfr, rounding_mode);
469  mpfr_clear(mpfr);
470  return this;
471 #else
472  const double x = mpf_get_d(mpf_);
473  if(isinf(x)) {
474  delete this;
475  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
476  } else {
477  return execute_libc_func< ::cos>(x);
478  }
479 #endif
480 }
481 
482 //------------------------------------------------------------------------------
483 // Name:
484 //------------------------------------------------------------------------------
485 knumber_base *knumber_float::tan() {
486 
487 #ifdef KNUMBER_USE_MPFR
488  mpfr_t mpfr;
489  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
490  mpfr_tan(mpfr, mpfr, rounding_mode);
491  mpfr_get_f(mpf_, mpfr, rounding_mode);
492  mpfr_clear(mpfr);
493  return this;
494 #else
495  const double x = mpf_get_d(mpf_);
496  if(isinf(x)) {
497  delete this;
498  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
499  } else {
500  return execute_libc_func< ::tan>(x);
501  }
502 #endif
503 }
504 
505 //------------------------------------------------------------------------------
506 // Name:
507 //------------------------------------------------------------------------------
508 knumber_base *knumber_float::asin() {
509  if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
510  delete this;
511  return new knumber_error(knumber_error::ERROR_UNDEFINED);
512  }
513 
514 #ifdef KNUMBER_USE_MPFR
515  mpfr_t mpfr;
516  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
517  mpfr_asin(mpfr, mpfr, rounding_mode);
518  mpfr_get_f(mpf_, mpfr, rounding_mode);
519  mpfr_clear(mpfr);
520  return this;
521 #else
522  const double x = mpf_get_d(mpf_);
523  if(isinf(x)) {
524  delete this;
525  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
526  } else {
527  return execute_libc_func< ::asin>(x);
528  }
529 #endif
530 }
531 
532 //------------------------------------------------------------------------------
533 // Name:
534 //------------------------------------------------------------------------------s
535 knumber_base *knumber_float::acos() {
536  if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
537  delete this;
538  return new knumber_error(knumber_error::ERROR_UNDEFINED);
539  }
540 
541 #ifdef KNUMBER_USE_MPFR
542  mpfr_t mpfr;
543  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
544  mpfr_acos(mpfr, mpfr, rounding_mode);
545  mpfr_get_f(mpf_, mpfr, rounding_mode);
546  mpfr_clear(mpfr);
547  return this;
548 #else
549  const double x = mpf_get_d(mpf_);
550  if(isinf(x)) {
551  delete this;
552  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
553  } else {
554  return execute_libc_func< ::acos>(x);
555  }
556 #endif
557 }
558 
559 //------------------------------------------------------------------------------
560 // Name:
561 //------------------------------------------------------------------------------
562 knumber_base *knumber_float::atan() {
563 
564 #ifdef KNUMBER_USE_MPFR
565  mpfr_t mpfr;
566  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
567  mpfr_atan(mpfr, mpfr, rounding_mode);
568  mpfr_get_f(mpf_, mpfr, rounding_mode);
569  mpfr_clear(mpfr);
570  return this;
571 #else
572  const double x = mpf_get_d(mpf_);
573  if(isinf(x)) {
574  delete this;
575  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
576  } else {
577  return execute_libc_func< ::atan>(x);
578  }
579 #endif
580 }
581 
582 //------------------------------------------------------------------------------
583 // Name:
584 //------------------------------------------------------------------------------
585 knumber_base *knumber_float::sinh() {
586 #ifdef KNUMBER_USE_MPFR
587  mpfr_t mpfr;
588  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
589  mpfr_sinh(mpfr, mpfr, rounding_mode);
590  mpfr_get_f(mpf_, mpfr, rounding_mode);
591  mpfr_clear(mpfr);
592  return this;
593 #else
594  const double x = mpf_get_d(mpf_);
595  return execute_libc_func< ::sinh>(x);
596 #endif
597 
598 }
599 
600 //------------------------------------------------------------------------------
601 // Name:
602 //------------------------------------------------------------------------------
603 knumber_base *knumber_float::cosh() {
604 #ifdef KNUMBER_USE_MPFR
605  mpfr_t mpfr;
606  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
607  mpfr_cosh(mpfr, mpfr, rounding_mode);
608  mpfr_get_f(mpf_, mpfr, rounding_mode);
609  mpfr_clear(mpfr);
610  return this;
611 #else
612  const double x = mpf_get_d(mpf_);
613  return execute_libc_func< ::cosh>(x);
614 #endif
615 }
616 
617 //------------------------------------------------------------------------------
618 // Name:
619 //------------------------------------------------------------------------------
620 knumber_base *knumber_float::tanh() {
621 #ifdef KNUMBER_USE_MPFR
622  mpfr_t mpfr;
623  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
624  mpfr_tanh(mpfr, mpfr, rounding_mode);
625  mpfr_get_f(mpf_, mpfr, rounding_mode);
626  mpfr_clear(mpfr);
627  return this;
628 #else
629  const double x = mpf_get_d(mpf_);
630  return execute_libc_func< ::tanh>(x);
631 #endif
632 }
633 
634 //------------------------------------------------------------------------------
635 // Name:
636 //------------------------------------------------------------------------------
637 knumber_base *knumber_float::asinh() {
638 #ifdef KNUMBER_USE_MPFR
639  mpfr_t mpfr;
640  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
641  mpfr_asinh(mpfr, mpfr, rounding_mode);
642  mpfr_get_f(mpf_, mpfr, rounding_mode);
643  mpfr_clear(mpfr);
644  return this;
645 #else
646  const double x = mpf_get_d(mpf_);
647  return execute_libc_func< ::asinh>(x);
648 #endif
649 }
650 
651 //------------------------------------------------------------------------------
652 // Name:
653 //------------------------------------------------------------------------------
654 knumber_base *knumber_float::acosh() {
655 #ifdef KNUMBER_USE_MPFR
656  mpfr_t mpfr;
657  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
658  mpfr_acosh(mpfr, mpfr, rounding_mode);
659  mpfr_get_f(mpf_, mpfr, rounding_mode);
660  mpfr_clear(mpfr);
661  return this;
662 #else
663  const double x = mpf_get_d(mpf_);
664  return execute_libc_func< ::acosh>(x);
665 #endif
666 }
667 
668 //------------------------------------------------------------------------------
669 // Name:
670 //------------------------------------------------------------------------------
671 knumber_base *knumber_float::atanh() {
672 #ifdef KNUMBER_USE_MPFR
673  mpfr_t mpfr;
674  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
675  mpfr_atanh(mpfr, mpfr, rounding_mode);
676  mpfr_get_f(mpf_, mpfr, rounding_mode);
677  mpfr_clear(mpfr);
678  return this;
679 #else
680  const double x = mpf_get_d(mpf_);
681  return execute_libc_func< ::atanh>(x);
682 #endif
683 }
684 
685 //------------------------------------------------------------------------------
686 // Name:
687 //------------------------------------------------------------------------------
688 knumber_base *knumber_float::pow(knumber_base *rhs) {
689 
690  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
691  mpf_pow_ui(mpf_, mpf_, mpz_get_ui(p->mpz_));
692 
693  if(p->sign() < 0) {
694  return reciprocal();
695  } else {
696  return this;
697  }
698  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
699  return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(p->mpf_));
700  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
701  knumber_float f(p);
702  return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(f.mpf_));
703  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
704  if(p->sign() > 0) {
705  knumber_error *e = new knumber_error(knumber_error::ERROR_POS_INFINITY);
706  delete this;
707  return e;
708  } else if(p->sign() < 0) {
709  knumber_integer *n = new knumber_integer(0);
710  delete this;
711  return n;
712  } else {
713  knumber_error *e = new knumber_error(knumber_error::ERROR_UNDEFINED);
714  delete this;
715  return e;
716  }
717  }
718 
719  Q_ASSERT(0);
720  return 0;
721 }
722 
723 //------------------------------------------------------------------------------
724 // Name:
725 //------------------------------------------------------------------------------
726 int knumber_float::compare(knumber_base *rhs) {
727 
728  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
729  knumber_float f(p);
730  return compare(&f);
731  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
732  return mpf_cmp(mpf_, p->mpf_);
733  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
734  knumber_float f(p);
735  return compare(&f);
736  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
737  // NOTE: any number compared to NaN/Inf/-Inf always compares less
738  // at the moment
739  return -1;
740  }
741 
742  Q_ASSERT(0);
743  return 0;
744 }
745 
746 //------------------------------------------------------------------------------
747 // Name:
748 //------------------------------------------------------------------------------
749 QString knumber_float::toString(int precision) const {
750 
751  size_t size;
752  if (precision > 0) {
753  size = gmp_snprintf(NULL, 0, "%.*Fg", precision, mpf_) + 1;
754  } else {
755  size = gmp_snprintf(NULL, 0, "%.Fg", mpf_) + 1;
756  }
757 
758  QScopedArrayPointer<char> buf(new char[size]);
759 
760  if (precision > 0) {
761  gmp_snprintf(&buf[0], size, "%.*Fg", precision, mpf_);
762  } else {
763  gmp_snprintf(&buf[0], size, "%.Fg", mpf_);
764  }
765 
766  return QLatin1String(&buf[0]);
767 }
768 
769 //------------------------------------------------------------------------------
770 // Name:
771 //------------------------------------------------------------------------------
772 bool knumber_float::is_integer() const {
773 
774  return mpf_integer_p(mpf_) != 0;
775 }
776 
777 //------------------------------------------------------------------------------
778 // Name:
779 //------------------------------------------------------------------------------
780 bool knumber_float::is_zero() const {
781 
782  return mpf_sgn(mpf_) == 0;
783 }
784 
785 //------------------------------------------------------------------------------
786 // Name:
787 //------------------------------------------------------------------------------
788 int knumber_float::sign() const {
789 
790  return mpf_sgn(mpf_);
791 }
792 
793 //------------------------------------------------------------------------------
794 // Name:
795 //------------------------------------------------------------------------------
796 knumber_base *knumber_float::reciprocal() {
797 
798  mpf_t mpf;
799  mpf_init_set_d(mpf, 1.0);
800  mpf_div(mpf_, mpf, mpf_);
801  return this;
802 }
803 
804 //------------------------------------------------------------------------------
805 // Name:
806 //------------------------------------------------------------------------------
807 knumber_base *knumber_float::log2() {
808 #ifdef KNUMBER_USE_MPFR
809  mpfr_t mpfr;
810  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
811  mpfr_log2(mpfr, mpfr, rounding_mode);
812  mpfr_get_f(mpf_, mpfr, rounding_mode);
813  mpfr_clear(mpfr);
814  return this;
815 #else
816  const double x = mpf_get_d(mpf_);
817  if(isinf(x)) {
818  delete this;
819  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
820  } else {
821  return execute_libc_func< ::log2>(x);
822  }
823 #endif
824 }
825 
826 //------------------------------------------------------------------------------
827 // Name:
828 //------------------------------------------------------------------------------
829 knumber_base *knumber_float::log10() {
830 #ifdef KNUMBER_USE_MPFR
831  mpfr_t mpfr;
832  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
833  mpfr_log10(mpfr, mpfr, rounding_mode);
834  mpfr_get_f(mpf_, mpfr, rounding_mode);
835  mpfr_clear(mpfr);
836  return this;
837 #else
838  const double x = mpf_get_d(mpf_);
839  if(isinf(x)) {
840  delete this;
841  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
842  } else {
843  return execute_libc_func< ::log10>(x);
844  }
845 #endif
846 }
847 
848 //------------------------------------------------------------------------------
849 // Name:
850 //------------------------------------------------------------------------------
851 knumber_base *knumber_float::ln() {
852 #ifdef KNUMBER_USE_MPFR
853  mpfr_t mpfr;
854  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
855  mpfr_log(mpfr, mpfr, rounding_mode);
856  mpfr_get_f(mpf_, mpfr, rounding_mode);
857  mpfr_clear(mpfr);
858  return this;
859 #else
860  const double x = mpf_get_d(mpf_);
861  if(isinf(x)) {
862  delete this;
863  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
864  } else {
865  return execute_libc_func< ::log>(x);
866  }
867 #endif
868 }
869 
870 //------------------------------------------------------------------------------
871 // Name:
872 //------------------------------------------------------------------------------
873 knumber_base *knumber_float::exp2() {
874 #ifdef KNUMBER_USE_MPFR
875  mpfr_t mpfr;
876  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
877  mpfr_exp2(mpfr, mpfr, rounding_mode);
878  mpfr_get_f(mpf_, mpfr, rounding_mode);
879  mpfr_clear(mpfr);
880  return this;
881 #else
882  const double x = mpf_get_d(mpf_);
883  if(isinf(x)) {
884  delete this;
885  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
886  } else {
887  return execute_libc_func< ::exp2>(x);
888  }
889 #endif
890 }
891 
892 //------------------------------------------------------------------------------
893 // Name:
894 //------------------------------------------------------------------------------
895 knumber_base *knumber_float::exp10() {
896 #ifdef KNUMBER_USE_MPFR
897  mpfr_t mpfr;
898  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
899  mpfr_exp10(mpfr, mpfr, rounding_mode);
900  mpfr_get_f(mpf_, mpfr, rounding_mode);
901  mpfr_clear(mpfr);
902  return this;
903 #else
904  const double x = mpf_get_d(mpf_);
905  if(isinf(x)) {
906  delete this;
907  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
908  } else {
909  return execute_libc_func< ::pow>(10, x);
910  }
911 #endif
912 }
913 
914 //------------------------------------------------------------------------------
915 // Name:
916 //------------------------------------------------------------------------------
917 knumber_base *knumber_float::exp() {
918 #ifdef KNUMBER_USE_MPFR
919  mpfr_t mpfr;
920  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
921  mpfr_exp(mpfr, mpfr, rounding_mode);
922  mpfr_get_f(mpf_, mpfr, rounding_mode);
923  mpfr_clear(mpfr);
924  return this;
925 #else
926  const double x = mpf_get_d(mpf_);
927  if(isinf(x)) {
928  delete this;
929  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
930  } else {
931  return execute_libc_func< ::exp>(x);
932  }
933 #endif
934 }
935 
936 //------------------------------------------------------------------------------
937 // Name:
938 //------------------------------------------------------------------------------
939 quint64 knumber_float::toUint64() const {
940  return knumber_integer(this).toUint64();
941 }
942 
943 //------------------------------------------------------------------------------
944 // Name:
945 //------------------------------------------------------------------------------
946 qint64 knumber_float::toInt64() const {
947  return knumber_integer(this).toInt64();
948 }
949 
950 //------------------------------------------------------------------------------
951 // Name:
952 //------------------------------------------------------------------------------
953 knumber_base *knumber_float::bin(knumber_base *rhs) {
954  Q_UNUSED(rhs);
955  delete this;
956  return new knumber_error(knumber_error::ERROR_UNDEFINED);
957 }
958 
959 }
detail::knumber_float::cosh
virtual knumber_base * cosh()
Definition: knumber_float.cpp:603
detail::knumber_float::tanh
virtual knumber_base * tanh()
Definition: knumber_float.cpp:620
detail::knumber_float::knumber_float
knumber_float(const QString &s)
Definition: knumber_float.cpp:87
detail::knumber_float::atanh
virtual knumber_base * atanh()
Definition: knumber_float.cpp:671
detail::knumber_float::add
virtual knumber_base * add(knumber_base *rhs)
Definition: knumber_float.cpp:171
detail::knumber_float::sqrt
virtual knumber_base * sqrt()
Definition: knumber_float.cpp:374
detail::knumber_float::tan
virtual knumber_base * tan()
Definition: knumber_float.cpp:485
detail::knumber_error::ERROR_NEG_INFINITY
Definition: knumber_error.h:38
detail::knumber_float::exp10
virtual knumber_base * exp10()
Definition: knumber_float.cpp:895
detail::knumber_float::mul
virtual knumber_base * mul(knumber_base *rhs)
Definition: knumber_float.cpp:219
exp
KNumber exp(const KNumber &x)
Definition: knumber_operators.cpp:230
detail::knumber_float::sign
virtual int sign() const
Definition: knumber_float.cpp:788
detail::knumber_float::knumber_integer
friend class knumber_integer
Definition: knumber_float.h:31
detail::knumber_float::pow
virtual knumber_base * pow(knumber_base *rhs)
Definition: knumber_float.cpp:688
detail::knumber_float::cbrt
virtual knumber_base * cbrt()
Definition: knumber_float.cpp:396
detail::knumber_float::toInt64
virtual qint64 toInt64() const
Definition: knumber_float.cpp:946
detail::knumber_base::is_zero
virtual bool is_zero() const =0
detail::knumber_float::bin
virtual knumber_base * bin(knumber_base *rhs)
Definition: knumber_float.cpp:953
detail::knumber_float::sin
virtual knumber_base * sin()
Definition: knumber_float.cpp:438
isnan
#define isnan(x)
Definition: knumber_float.cpp:40
detail::knumber_base
Definition: knumber_base.h:38
detail::knumber_fraction
Definition: knumber_fraction.h:28
detail::knumber_float::ln
virtual knumber_base * ln()
Definition: knumber_float.cpp:851
detail::knumber_float::toUint64
virtual quint64 toUint64() const
Definition: knumber_float.cpp:939
detail::knumber_integer
Definition: knumber_integer.h:28
detail::knumber_float::toString
virtual QString toString(int precision) const
Definition: knumber_float.cpp:749
exp2
KNumber exp2(const KNumber &x)
Definition: knumber_operators.cpp:216
detail::knumber_float::div
virtual knumber_base * div(knumber_base *rhs)
Definition: knumber_float.cpp:253
knumber_fraction.h
isinf
#define isinf(x)
Definition: knumber_float.cpp:36
detail::knumber_float::factorial
virtual knumber_base * factorial()
Definition: knumber_float.cpp:423
detail::knumber_float::bitwise_or
virtual knumber_base * bitwise_or(knumber_base *rhs)
Definition: knumber_float.cpp:327
detail::knumber_float::sub
virtual knumber_base * sub(knumber_base *rhs)
Definition: knumber_float.cpp:195
detail::knumber_float::bitwise_xor
virtual knumber_base * bitwise_xor(knumber_base *rhs)
Definition: knumber_float.cpp:317
detail::knumber_float::asinh
virtual knumber_base * asinh()
Definition: knumber_float.cpp:637
detail::knumber_float::cmp
virtual knumber_base * cmp()
Definition: knumber_float.cpp:356
detail::knumber_float::exp2
virtual knumber_base * exp2()
Definition: knumber_float.cpp:873
detail::knumber_float::acos
virtual knumber_base * acos()
Definition: knumber_float.cpp:535
detail::knumber_float::mod
virtual knumber_base * mod(knumber_base *rhs)
Definition: knumber_float.cpp:291
detail::knumber_float::exp
virtual knumber_base * exp()
Definition: knumber_float.cpp:917
detail::knumber_float::reciprocal
virtual knumber_base * reciprocal()
Definition: knumber_float.cpp:796
detail::knumber_float::log10
virtual knumber_base * log10()
Definition: knumber_float.cpp:829
knumber_integer.h
detail::knumber_float::acosh
virtual knumber_base * acosh()
Definition: knumber_float.cpp:654
detail::knumber_float::abs
virtual knumber_base * abs()
Definition: knumber_float.cpp:365
detail::knumber_error::ERROR_POS_INFINITY
Definition: knumber_error.h:37
detail::knumber_float::atan
virtual knumber_base * atan()
Definition: knumber_float.cpp:562
detail::knumber_float::cos
virtual knumber_base * cos()
Definition: knumber_float.cpp:462
detail::knumber_float::bitwise_shift
virtual knumber_base * bitwise_shift(knumber_base *rhs)
Definition: knumber_float.cpp:337
detail::knumber_float::asin
virtual knumber_base * asin()
Definition: knumber_float.cpp:508
detail::knumber_float
Definition: knumber_float.h:28
knumber_error.h
detail::knumber_float::compare
virtual int compare(knumber_base *rhs)
Definition: knumber_float.cpp:726
detail::knumber_float::knumber_error
friend class knumber_error
Definition: knumber_float.h:30
detail::knumber_float::clone
virtual knumber_base * clone()
Definition: knumber_float.cpp:155
knumber_float.h
detail::knumber_error
Definition: knumber_error.h:28
detail::knumber_float::neg
virtual knumber_base * neg()
Definition: knumber_float.cpp:347
detail::knumber_float::sinh
virtual knumber_base * sinh()
Definition: knumber_float.cpp:585
detail::knumber_float::is_integer
virtual bool is_integer() const
Definition: knumber_float.cpp:772
detail::knumber_float::log2
virtual knumber_base * log2()
Definition: knumber_float.cpp:807
detail::knumber_error::ERROR_UNDEFINED
Definition: knumber_error.h:36
exp10
KNumber exp10(const KNumber &x)
Definition: knumber_operators.cpp:223
detail::knumber_integer::factorial
virtual knumber_base * factorial()
Definition: knumber_integer.cpp:650
detail::knumber_float::~knumber_float
virtual ~knumber_float()
Definition: knumber_float.cpp:163
detail::knumber_float::bitwise_and
virtual knumber_base * bitwise_and(knumber_base *rhs)
Definition: knumber_float.cpp:307
detail::knumber_float::is_zero
virtual bool is_zero() const
Definition: knumber_float.cpp:780
log2
KNumber log2(const KNumber &x)
Definition: knumber_operators.cpp:195
detail::knumber_error::neg
virtual knumber_base * neg()
Definition: knumber_error.cpp:300
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:08:05 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kcalc

Skip menu "kcalc"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal