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

kcalc

  • sources
  • kde-4.14
  • 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  // NOTE: we don't support bitwise operations with non-integer operands
342  return new knumber_error(knumber_error::ERROR_UNDEFINED);
343 }
344 
345 //------------------------------------------------------------------------------
346 // Name:
347 //------------------------------------------------------------------------------
348 knumber_base *knumber_float::neg() {
349 
350  mpf_neg(mpf_, mpf_);
351  return this;
352 }
353 
354 //------------------------------------------------------------------------------
355 // Name:
356 //------------------------------------------------------------------------------
357 knumber_base *knumber_float::cmp() {
358 
359  delete this;
360  return new knumber_error(knumber_error::ERROR_UNDEFINED);
361 }
362 
363 //------------------------------------------------------------------------------
364 // Name:
365 //------------------------------------------------------------------------------
366 knumber_base *knumber_float::abs() {
367 
368  mpf_abs(mpf_, mpf_);
369  return this;
370 }
371 
372 //------------------------------------------------------------------------------
373 // Name:
374 //------------------------------------------------------------------------------
375 knumber_base *knumber_float::sqrt() {
376 
377  if(sign() < 0) {
378  delete this;
379  return new knumber_error(knumber_error::ERROR_UNDEFINED);
380  }
381 
382 #ifdef KNUMBER_USE_MPFR
383  mpfr_t mpfr;
384  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
385  mpfr_sqrt(mpfr, mpfr, rounding_mode);
386  mpfr_get_f(mpf_, mpfr, rounding_mode);
387  mpfr_clear(mpfr);
388 #else
389  mpf_sqrt(mpf_, mpf_);
390 #endif
391  return this;
392 }
393 
394 //------------------------------------------------------------------------------
395 // Name:
396 //------------------------------------------------------------------------------
397 knumber_base *knumber_float::cbrt() {
398 
399 #ifdef KNUMBER_USE_MPFR
400  mpfr_t mpfr;
401  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
402  mpfr_cbrt(mpfr, mpfr, rounding_mode);
403  mpfr_get_f(mpf_, mpfr, rounding_mode);
404  mpfr_clear(mpfr);
405 #else
406  const double x = mpf_get_d(mpf_);
407  if(isinf(x)) {
408  delete this;
409  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
410  } else {
411 #ifdef Q_CC_MSVC
412  return execute_libc_func< ::pow>(x, 1.0 / 3.0);
413 #else
414  return execute_libc_func< ::cbrt>(x);
415 #endif
416  }
417 #endif
418  return this;
419 }
420 
421 //------------------------------------------------------------------------------
422 // Name:
423 //------------------------------------------------------------------------------
424 knumber_base *knumber_float::factorial() {
425 
426  if(sign() < 0) {
427  delete this;
428  return new knumber_error(knumber_error::ERROR_UNDEFINED);
429  }
430 
431  knumber_integer *i = new knumber_integer(this);
432  delete this;
433  return i->factorial();
434 }
435 
436 //------------------------------------------------------------------------------
437 // Name:
438 //------------------------------------------------------------------------------
439 knumber_base *knumber_float::sin() {
440 
441 #ifdef KNUMBER_USE_MPFR
442  mpfr_t mpfr;
443  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
444  mpfr_sin(mpfr, mpfr, rounding_mode);
445  mpfr_get_f(mpf_, mpfr, rounding_mode);
446  mpfr_clear(mpfr);
447  return this;
448 #else
449  const double x = mpf_get_d(mpf_);
450  if(isinf(x)) {
451  delete this;
452  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
453  } else {
454  return execute_libc_func< ::sin>(x);
455  }
456 #endif
457 
458 }
459 
460 //------------------------------------------------------------------------------
461 // Name:
462 //------------------------------------------------------------------------------
463 knumber_base *knumber_float::floor() {
464 #ifdef KNUMBER_USE_MPFR
465  mpfr_t mpfr;
466  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
467  mpfr_floor(mpfr, mpfr);
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< ::floor>(x);
478  }
479 #endif
480 }
481 
482 //------------------------------------------------------------------------------
483 // Name:
484 //------------------------------------------------------------------------------
485 knumber_base *knumber_float::ceil() {
486 #ifdef KNUMBER_USE_MPFR
487  mpfr_t mpfr;
488  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
489  mpfr_ceil(mpfr, mpfr);
490  mpfr_get_f(mpf_, mpfr, rounding_mode);
491  mpfr_clear(mpfr);
492  return this;
493 #else
494  const double x = mpf_get_d(mpf_);
495  if(isinf(x)) {
496  delete this;
497  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
498  } else {
499  return execute_libc_func< ::ceil>(x);
500  }
501 #endif
502 }
503 //------------------------------------------------------------------------------
504 // Name:
505 //------------------------------------------------------------------------------
506 knumber_base *knumber_float::cos() {
507 
508 #ifdef KNUMBER_USE_MPFR
509  mpfr_t mpfr;
510  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
511  mpfr_cos(mpfr, mpfr, rounding_mode);
512  mpfr_get_f(mpf_, mpfr, rounding_mode);
513  mpfr_clear(mpfr);
514  return this;
515 #else
516  const double x = mpf_get_d(mpf_);
517  if(isinf(x)) {
518  delete this;
519  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
520  } else {
521  return execute_libc_func< ::cos>(x);
522  }
523 #endif
524 }
525 
526 //------------------------------------------------------------------------------
527 // Name:
528 //------------------------------------------------------------------------------
529 knumber_base *knumber_float::tan() {
530 
531 #ifdef KNUMBER_USE_MPFR
532  mpfr_t mpfr;
533  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
534  mpfr_tan(mpfr, mpfr, rounding_mode);
535  mpfr_get_f(mpf_, mpfr, rounding_mode);
536  mpfr_clear(mpfr);
537  return this;
538 #else
539  const double x = mpf_get_d(mpf_);
540  if(isinf(x)) {
541  delete this;
542  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
543  } else {
544  return execute_libc_func< ::tan>(x);
545  }
546 #endif
547 }
548 
549 //------------------------------------------------------------------------------
550 // Name:
551 //------------------------------------------------------------------------------
552 knumber_base *knumber_float::asin() {
553  if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
554  delete this;
555  return new knumber_error(knumber_error::ERROR_UNDEFINED);
556  }
557 
558 #ifdef KNUMBER_USE_MPFR
559  mpfr_t mpfr;
560  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
561  mpfr_asin(mpfr, mpfr, rounding_mode);
562  mpfr_get_f(mpf_, mpfr, rounding_mode);
563  mpfr_clear(mpfr);
564  return this;
565 #else
566  const double x = mpf_get_d(mpf_);
567  if(isinf(x)) {
568  delete this;
569  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
570  } else {
571  return execute_libc_func< ::asin>(x);
572  }
573 #endif
574 }
575 
576 //------------------------------------------------------------------------------
577 // Name:
578 //------------------------------------------------------------------------------s
579 knumber_base *knumber_float::acos() {
580  if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
581  delete this;
582  return new knumber_error(knumber_error::ERROR_UNDEFINED);
583  }
584 
585 #ifdef KNUMBER_USE_MPFR
586  mpfr_t mpfr;
587  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
588  mpfr_acos(mpfr, mpfr, rounding_mode);
589  mpfr_get_f(mpf_, mpfr, rounding_mode);
590  mpfr_clear(mpfr);
591  return this;
592 #else
593  const double x = mpf_get_d(mpf_);
594  if(isinf(x)) {
595  delete this;
596  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
597  } else {
598  return execute_libc_func< ::acos>(x);
599  }
600 #endif
601 }
602 
603 //------------------------------------------------------------------------------
604 // Name:
605 //------------------------------------------------------------------------------
606 knumber_base *knumber_float::atan() {
607 
608 #ifdef KNUMBER_USE_MPFR
609  mpfr_t mpfr;
610  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
611  mpfr_atan(mpfr, mpfr, rounding_mode);
612  mpfr_get_f(mpf_, mpfr, rounding_mode);
613  mpfr_clear(mpfr);
614  return this;
615 #else
616  const double x = mpf_get_d(mpf_);
617  if(isinf(x)) {
618  delete this;
619  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
620  } else {
621  return execute_libc_func< ::atan>(x);
622  }
623 #endif
624 }
625 
626 //------------------------------------------------------------------------------
627 // Name:
628 //------------------------------------------------------------------------------
629 knumber_base *knumber_float::sinh() {
630 #ifdef KNUMBER_USE_MPFR
631  mpfr_t mpfr;
632  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
633  mpfr_sinh(mpfr, mpfr, rounding_mode);
634  mpfr_get_f(mpf_, mpfr, rounding_mode);
635  mpfr_clear(mpfr);
636  return this;
637 #else
638  const double x = mpf_get_d(mpf_);
639  return execute_libc_func< ::sinh>(x);
640 #endif
641 
642 }
643 
644 //------------------------------------------------------------------------------
645 // Name:
646 //------------------------------------------------------------------------------
647 knumber_base *knumber_float::cosh() {
648 #ifdef KNUMBER_USE_MPFR
649  mpfr_t mpfr;
650  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
651  mpfr_cosh(mpfr, mpfr, rounding_mode);
652  mpfr_get_f(mpf_, mpfr, rounding_mode);
653  mpfr_clear(mpfr);
654  return this;
655 #else
656  const double x = mpf_get_d(mpf_);
657  return execute_libc_func< ::cosh>(x);
658 #endif
659 }
660 
661 //------------------------------------------------------------------------------
662 // Name:
663 //------------------------------------------------------------------------------
664 knumber_base *knumber_float::tanh() {
665 #ifdef KNUMBER_USE_MPFR
666  mpfr_t mpfr;
667  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
668  mpfr_tanh(mpfr, mpfr, rounding_mode);
669  mpfr_get_f(mpf_, mpfr, rounding_mode);
670  mpfr_clear(mpfr);
671  return this;
672 #else
673  const double x = mpf_get_d(mpf_);
674  return execute_libc_func< ::tanh>(x);
675 #endif
676 }
677 
678 //------------------------------------------------------------------------------
679 // Name:
680 //------------------------------------------------------------------------------
681 knumber_base *knumber_float::tgamma() {
682 
683 #ifdef KNUMBER_USE_MPFR
684  mpfr_t mpfr;
685  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
686  mpfr_gamma(mpfr, mpfr, rounding_mode);
687  mpfr_get_f(mpf_, mpfr, rounding_mode);
688  mpfr_clear(mpfr);
689  return this;
690 #else
691  const double x = mpf_get_d(mpf_);
692  if(isinf(x)) {
693  delete this;
694  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
695 
696  } else {
697  return execute_libc_func< ::tgamma>(x);
698  }
699 #endif
700 
701 }
702 
703 //------------------------------------------------------------------------------
704 // Name:
705 //------------------------------------------------------------------------------
706 knumber_base *knumber_float::asinh() {
707 #ifdef KNUMBER_USE_MPFR
708  mpfr_t mpfr;
709  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
710  mpfr_asinh(mpfr, mpfr, rounding_mode);
711  mpfr_get_f(mpf_, mpfr, rounding_mode);
712  mpfr_clear(mpfr);
713  return this;
714 #else
715  const double x = mpf_get_d(mpf_);
716  return execute_libc_func< ::asinh>(x);
717 #endif
718 }
719 
720 //------------------------------------------------------------------------------
721 // Name:
722 //------------------------------------------------------------------------------
723 knumber_base *knumber_float::acosh() {
724 #ifdef KNUMBER_USE_MPFR
725  mpfr_t mpfr;
726  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
727  mpfr_acosh(mpfr, mpfr, rounding_mode);
728  mpfr_get_f(mpf_, mpfr, rounding_mode);
729  mpfr_clear(mpfr);
730  return this;
731 #else
732  const double x = mpf_get_d(mpf_);
733  return execute_libc_func< ::acosh>(x);
734 #endif
735 }
736 
737 //------------------------------------------------------------------------------
738 // Name:
739 //------------------------------------------------------------------------------
740 knumber_base *knumber_float::atanh() {
741 #ifdef KNUMBER_USE_MPFR
742  mpfr_t mpfr;
743  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
744  mpfr_atanh(mpfr, mpfr, rounding_mode);
745  mpfr_get_f(mpf_, mpfr, rounding_mode);
746  mpfr_clear(mpfr);
747  return this;
748 #else
749  const double x = mpf_get_d(mpf_);
750  return execute_libc_func< ::atanh>(x);
751 #endif
752 }
753 
754 //------------------------------------------------------------------------------
755 // Name:
756 //------------------------------------------------------------------------------
757 knumber_base *knumber_float::pow(knumber_base *rhs) {
758 
759  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
760  mpf_pow_ui(mpf_, mpf_, mpz_get_ui(p->mpz_));
761 
762  if(p->sign() < 0) {
763  return reciprocal();
764  } else {
765  return this;
766  }
767  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
768  return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(p->mpf_));
769  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
770  knumber_float f(p);
771  return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(f.mpf_));
772  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
773  if(p->sign() > 0) {
774  knumber_error *e = new knumber_error(knumber_error::ERROR_POS_INFINITY);
775  delete this;
776  return e;
777  } else if(p->sign() < 0) {
778  knumber_integer *n = new knumber_integer(0);
779  delete this;
780  return n;
781  } else {
782  knumber_error *e = new knumber_error(knumber_error::ERROR_UNDEFINED);
783  delete this;
784  return e;
785  }
786  }
787 
788  Q_ASSERT(0);
789  return 0;
790 }
791 
792 //------------------------------------------------------------------------------
793 // Name:
794 //------------------------------------------------------------------------------
795 int knumber_float::compare(knumber_base *rhs) {
796 
797  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
798  knumber_float f(p);
799  return compare(&f);
800  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
801  return mpf_cmp(mpf_, p->mpf_);
802  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
803  knumber_float f(p);
804  return compare(&f);
805  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
806  // NOTE: any number compared to NaN/Inf/-Inf always compares less
807  // at the moment
808  return -1;
809  }
810 
811  Q_ASSERT(0);
812  return 0;
813 }
814 
815 //------------------------------------------------------------------------------
816 // Name:
817 //------------------------------------------------------------------------------
818 QString knumber_float::toString(int precision) const {
819 
820  size_t size;
821  if (precision > 0) {
822  size = gmp_snprintf(NULL, 0, "%.*Fg", precision, mpf_) + 1;
823  } else {
824  size = gmp_snprintf(NULL, 0, "%.Fg", mpf_) + 1;
825  }
826 
827  QScopedArrayPointer<char> buf(new char[size]);
828 
829  if (precision > 0) {
830  gmp_snprintf(&buf[0], size, "%.*Fg", precision, mpf_);
831  } else {
832  gmp_snprintf(&buf[0], size, "%.Fg", mpf_);
833  }
834 
835  return QLatin1String(&buf[0]);
836 }
837 
838 //------------------------------------------------------------------------------
839 // Name:
840 //------------------------------------------------------------------------------
841 bool knumber_float::is_integer() const {
842 
843  return mpf_integer_p(mpf_) != 0;
844 }
845 
846 //------------------------------------------------------------------------------
847 // Name:
848 //------------------------------------------------------------------------------
849 bool knumber_float::is_zero() const {
850 
851  return mpf_sgn(mpf_) == 0;
852 }
853 
854 //------------------------------------------------------------------------------
855 // Name:
856 //------------------------------------------------------------------------------
857 int knumber_float::sign() const {
858 
859  return mpf_sgn(mpf_);
860 }
861 
862 //------------------------------------------------------------------------------
863 // Name:
864 //------------------------------------------------------------------------------
865 knumber_base *knumber_float::reciprocal() {
866 
867  mpf_t mpf;
868  mpf_init_set_d(mpf, 1.0);
869  mpf_div(mpf_, mpf, mpf_);
870  return this;
871 }
872 
873 //------------------------------------------------------------------------------
874 // Name:
875 //------------------------------------------------------------------------------
876 knumber_base *knumber_float::log2() {
877 #ifdef KNUMBER_USE_MPFR
878  mpfr_t mpfr;
879  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
880  mpfr_log2(mpfr, mpfr, rounding_mode);
881  mpfr_get_f(mpf_, mpfr, rounding_mode);
882  mpfr_clear(mpfr);
883  return this;
884 #else
885  const double x = mpf_get_d(mpf_);
886  if(isinf(x)) {
887  delete this;
888  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
889  } else {
890  return execute_libc_func< ::log2>(x);
891  }
892 #endif
893 }
894 
895 //------------------------------------------------------------------------------
896 // Name:
897 //------------------------------------------------------------------------------
898 knumber_base *knumber_float::log10() {
899 #ifdef KNUMBER_USE_MPFR
900  mpfr_t mpfr;
901  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
902  mpfr_log10(mpfr, mpfr, rounding_mode);
903  mpfr_get_f(mpf_, mpfr, rounding_mode);
904  mpfr_clear(mpfr);
905  return this;
906 #else
907  const double x = mpf_get_d(mpf_);
908  if(isinf(x)) {
909  delete this;
910  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
911  } else {
912  return execute_libc_func< ::log10>(x);
913  }
914 #endif
915 }
916 
917 //------------------------------------------------------------------------------
918 // Name:
919 //------------------------------------------------------------------------------
920 knumber_base *knumber_float::ln() {
921 #ifdef KNUMBER_USE_MPFR
922  mpfr_t mpfr;
923  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
924  mpfr_log(mpfr, mpfr, rounding_mode);
925  mpfr_get_f(mpf_, mpfr, rounding_mode);
926  mpfr_clear(mpfr);
927  return this;
928 #else
929  const double x = mpf_get_d(mpf_);
930  if(isinf(x)) {
931  delete this;
932  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
933  } else {
934  return execute_libc_func< ::log>(x);
935  }
936 #endif
937 }
938 
939 //------------------------------------------------------------------------------
940 // Name:
941 //------------------------------------------------------------------------------
942 knumber_base *knumber_float::exp2() {
943 #ifdef KNUMBER_USE_MPFR
944  mpfr_t mpfr;
945  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
946  mpfr_exp2(mpfr, mpfr, rounding_mode);
947  mpfr_get_f(mpf_, mpfr, rounding_mode);
948  mpfr_clear(mpfr);
949  return this;
950 #else
951  const double x = mpf_get_d(mpf_);
952  if(isinf(x)) {
953  delete this;
954  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
955  } else {
956  return execute_libc_func< ::exp2>(x);
957  }
958 #endif
959 }
960 
961 //------------------------------------------------------------------------------
962 // Name:
963 //------------------------------------------------------------------------------
964 knumber_base *knumber_float::exp10() {
965 #ifdef KNUMBER_USE_MPFR
966  mpfr_t mpfr;
967  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
968  mpfr_exp10(mpfr, mpfr, rounding_mode);
969  mpfr_get_f(mpf_, mpfr, rounding_mode);
970  mpfr_clear(mpfr);
971  return this;
972 #else
973  const double x = mpf_get_d(mpf_);
974  if(isinf(x)) {
975  delete this;
976  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
977  } else {
978  return execute_libc_func< ::pow>(10, x);
979  }
980 #endif
981 }
982 
983 //------------------------------------------------------------------------------
984 // Name:
985 //------------------------------------------------------------------------------
986 knumber_base *knumber_float::exp() {
987 #ifdef KNUMBER_USE_MPFR
988  mpfr_t mpfr;
989  mpfr_init_set_f(mpfr, mpf_, rounding_mode);
990  mpfr_exp(mpfr, mpfr, rounding_mode);
991  mpfr_get_f(mpf_, mpfr, rounding_mode);
992  mpfr_clear(mpfr);
993  return this;
994 #else
995  const double x = mpf_get_d(mpf_);
996  if(isinf(x)) {
997  delete this;
998  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
999  } else {
1000  return execute_libc_func< ::exp>(x);
1001  }
1002 #endif
1003 }
1004 
1005 //------------------------------------------------------------------------------
1006 // Name:
1007 //------------------------------------------------------------------------------
1008 quint64 knumber_float::toUint64() const {
1009  return knumber_integer(this).toUint64();
1010 }
1011 
1012 //------------------------------------------------------------------------------
1013 // Name:
1014 //------------------------------------------------------------------------------
1015 qint64 knumber_float::toInt64() const {
1016  return knumber_integer(this).toInt64();
1017 }
1018 
1019 //------------------------------------------------------------------------------
1020 // Name:
1021 //------------------------------------------------------------------------------
1022 knumber_base *knumber_float::bin(knumber_base *rhs) {
1023  Q_UNUSED(rhs);
1024  delete this;
1025  return new knumber_error(knumber_error::ERROR_UNDEFINED);
1026 }
1027 
1028 }
detail::knumber_float::cosh
virtual knumber_base * cosh()
Definition: knumber_float.cpp:647
detail::knumber_float::floor
virtual knumber_base * floor()
Definition: knumber_float.cpp:463
detail::knumber_float::tanh
virtual knumber_base * tanh()
Definition: knumber_float.cpp:664
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:740
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:375
detail::knumber_float::tan
virtual knumber_base * tan()
Definition: knumber_float.cpp:529
detail::knumber_error::ERROR_NEG_INFINITY
Definition: knumber_error.h:38
detail::knumber_float::exp10
virtual knumber_base * exp10()
Definition: knumber_float.cpp:964
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:252
detail::knumber_float::sign
virtual int sign() const
Definition: knumber_float.cpp:857
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:757
detail::knumber_float::cbrt
virtual knumber_base * cbrt()
Definition: knumber_float.cpp:397
detail::knumber_float::toInt64
virtual qint64 toInt64() const
Definition: knumber_float.cpp:1015
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:1022
detail::knumber_float::sin
virtual knumber_base * sin()
Definition: knumber_float.cpp:439
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:920
detail::knumber_float::toUint64
virtual quint64 toUint64() const
Definition: knumber_float.cpp:1008
detail::knumber_float::tgamma
virtual knumber_base * tgamma()
Definition: knumber_float.cpp:681
detail::knumber_integer
Definition: knumber_integer.h:28
detail::knumber_float::toString
virtual QString toString(int precision) const
Definition: knumber_float.cpp:818
exp2
KNumber exp2(const KNumber &x)
Definition: knumber_operators.cpp:238
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:424
detail::knumber_float::bitwise_or
virtual knumber_base * bitwise_or(knumber_base *rhs)
Definition: knumber_float.cpp:327
QString
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:706
detail::knumber_float::cmp
virtual knumber_base * cmp()
Definition: knumber_float.cpp:357
detail::knumber_float::exp2
virtual knumber_base * exp2()
Definition: knumber_float.cpp:942
detail::knumber_float::acos
virtual knumber_base * acos()
Definition: knumber_float.cpp:579
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:986
detail::knumber_float::reciprocal
virtual knumber_base * reciprocal()
Definition: knumber_float.cpp:865
detail::knumber_float::log10
virtual knumber_base * log10()
Definition: knumber_float.cpp:898
knumber_integer.h
detail::knumber_float::acosh
virtual knumber_base * acosh()
Definition: knumber_float.cpp:723
detail::knumber_float::abs
virtual knumber_base * abs()
Definition: knumber_float.cpp:366
detail::knumber_error::ERROR_POS_INFINITY
Definition: knumber_error.h:37
detail::knumber_float::atan
virtual knumber_base * atan()
Definition: knumber_float.cpp:606
QLatin1String
detail::knumber_float::cos
virtual knumber_base * cos()
Definition: knumber_float.cpp:506
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:552
detail::knumber_float
Definition: knumber_float.h:28
knumber_error.h
QScopedArrayPointer
detail::knumber_float::compare
virtual int compare(knumber_base *rhs)
Definition: knumber_float.cpp:795
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::ceil
virtual knumber_base * ceil()
Definition: knumber_float.cpp:485
detail::knumber_float::neg
virtual knumber_base * neg()
Definition: knumber_float.cpp:348
detail::knumber_float::sinh
virtual knumber_base * sinh()
Definition: knumber_float.cpp:629
detail::knumber_float::is_integer
virtual bool is_integer() const
Definition: knumber_float.cpp:841
detail::knumber_float::log2
virtual knumber_base * log2()
Definition: knumber_float.cpp:876
detail::knumber_error::ERROR_UNDEFINED
Definition: knumber_error.h:36
exp10
KNumber exp10(const KNumber &x)
Definition: knumber_operators.cpp:245
detail::knumber_integer::factorial
virtual knumber_base * factorial()
Definition: knumber_integer.cpp:660
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:849
log2
KNumber log2(const KNumber &x)
Definition: knumber_operators.cpp:203
detail::knumber_error::neg
virtual knumber_base * neg()
Definition: knumber_error.cpp:300
QString::toAscii
QByteArray toAscii() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:42:28 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
  • ktimer
  • kwallet
  • 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