• 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_fraction.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 
27 namespace detail {
28 
29 bool knumber_fraction::default_fractional_input = false;
30 bool knumber_fraction::default_fractional_output = true;
31 bool knumber_fraction::split_off_integer_for_fraction_output = false;
32 
33 //------------------------------------------------------------------------------
34 // Name:
35 //------------------------------------------------------------------------------
36 void knumber_fraction::set_default_fractional_input(bool value) {
37  default_fractional_input = value;
38 }
39 
40 //------------------------------------------------------------------------------
41 // Name:
42 //------------------------------------------------------------------------------
43 void knumber_fraction::set_default_fractional_output(bool value) {
44  default_fractional_output = value;
45 }
46 
47 //------------------------------------------------------------------------------
48 // Name:
49 //------------------------------------------------------------------------------
50 void knumber_fraction::set_split_off_integer_for_fraction_output(bool value) {
51  split_off_integer_for_fraction_output = value;
52 }
53 
54 //------------------------------------------------------------------------------
55 // Name:
56 //------------------------------------------------------------------------------
57 knumber_fraction::knumber_fraction(const QString &s) {
58  mpq_init(mpq_);
59  mpq_set_str(mpq_, s.toAscii(), 10);
60  mpq_canonicalize(mpq_);
61 }
62 
63 //------------------------------------------------------------------------------
64 // Name:
65 //------------------------------------------------------------------------------
66 knumber_fraction::knumber_fraction(qint64 num, quint64 den) {
67  mpq_init(mpq_);
68  mpq_set_si(mpq_, num, den);
69  mpq_canonicalize(mpq_);
70 }
71 
72 //------------------------------------------------------------------------------
73 // Name:
74 //------------------------------------------------------------------------------
75 knumber_fraction::knumber_fraction(quint64 num, quint64 den) {
76  mpq_init(mpq_);
77  mpq_set_ui(mpq_, num, den);
78  mpq_canonicalize(mpq_);
79 }
80 
81 //------------------------------------------------------------------------------
82 // Name:
83 //------------------------------------------------------------------------------
84 knumber_fraction::knumber_fraction(mpq_t mpq) {
85  mpq_init(mpq_);
86  mpq_set(mpq_, mpq);
87 }
88 
89 //------------------------------------------------------------------------------
90 // Name:
91 //------------------------------------------------------------------------------
92 knumber_fraction::knumber_fraction(const knumber_fraction *value) {
93  mpq_init(mpq_);
94  mpq_set(mpq_, value->mpq_);
95 }
96 
97 //------------------------------------------------------------------------------
98 // Name:
99 //------------------------------------------------------------------------------
100 knumber_fraction::knumber_fraction(const knumber_integer *value) {
101  mpq_init(mpq_);
102  mpq_set_z(mpq_, value->mpz_);
103 }
104 
105 #if 0
106 //------------------------------------------------------------------------------
107 // Name:
108 //------------------------------------------------------------------------------
109 knumber_fraction::knumber_fraction(const knumber_float *value) {
110  mpq_init(mpq_);
111  mpq_set_f(mpq_, value->mpf_);
112 }
113 #endif
114 
115 //------------------------------------------------------------------------------
116 // Name:
117 //------------------------------------------------------------------------------
118 knumber_base *knumber_fraction::clone() {
119  return new knumber_fraction(this);
120 }
121 
122 //------------------------------------------------------------------------------
123 // Name:
124 //------------------------------------------------------------------------------
125 knumber_fraction::~knumber_fraction() {
126  mpq_clear(mpq_);
127 }
128 
129 //------------------------------------------------------------------------------
130 // Name:
131 //------------------------------------------------------------------------------
132 bool knumber_fraction::is_integer() const {
133  return (mpz_cmp_ui(mpq_denref(mpq_), 1) == 0);
134 }
135 
136 //------------------------------------------------------------------------------
137 // Name:
138 //------------------------------------------------------------------------------
139 knumber_base *knumber_fraction::add(knumber_base *rhs) {
140 
141  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
142  knumber_fraction q(p);
143  mpq_add(mpq_, mpq_, q.mpq_);
144  return this;
145  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
146  knumber_float *f = new knumber_float(this);
147  delete this;
148  return f->add(p);
149  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
150  mpq_add(mpq_, mpq_, p->mpq_);
151  return this;
152  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
153  knumber_error *e = new knumber_error(p);
154  delete this;
155  return e;
156  }
157 
158  Q_ASSERT(0);
159  return 0;
160 }
161 
162 //------------------------------------------------------------------------------
163 // Name:
164 //------------------------------------------------------------------------------
165 knumber_base *knumber_fraction::sub(knumber_base *rhs) {
166 
167  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
168  knumber_fraction q(p);
169  mpq_sub(mpq_, mpq_, q.mpq_);
170  return this;
171  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
172  knumber_float *f = new knumber_float(this);
173  delete this;
174  return f->sub(p);
175  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
176  mpq_sub(mpq_, mpq_, p->mpq_);
177  return this;
178  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
179  knumber_error *e = new knumber_error(p);
180  delete this;
181  return e->neg();
182  }
183 
184  Q_ASSERT(0);
185  return 0;
186 }
187 
188 //------------------------------------------------------------------------------
189 // Name:
190 //------------------------------------------------------------------------------
191 knumber_base *knumber_fraction::mul(knumber_base *rhs) {
192 
193  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
194  knumber_fraction q(p);
195  mpq_mul(mpq_, mpq_, q.mpq_);
196  return this;
197  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
198  knumber_float *q = new knumber_float(this);
199  delete this;
200  return q->mul(p);
201  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
202  mpq_mul(mpq_, mpq_, p->mpq_);
203  return this;
204  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
205  if(is_zero()) {
206  delete this;
207  knumber_error *e = new knumber_error(knumber_error::ERROR_UNDEFINED);
208  return e;
209  }
210 
211  if(sign() < 0) {
212  delete this;
213  knumber_error *e = new knumber_error(p);
214  return e->neg();
215  } else {
216  delete this;
217  knumber_error *e = new knumber_error(p);
218  return e;
219  }
220  }
221 
222  Q_ASSERT(0);
223  return 0;
224 }
225 
226 //------------------------------------------------------------------------------
227 // Name:
228 //------------------------------------------------------------------------------
229 knumber_base *knumber_fraction::div(knumber_base *rhs) {
230 
231  if(rhs->is_zero()) {
232  if(sign() < 0) {
233  delete this;
234  return new knumber_error(knumber_error::ERROR_NEG_INFINITY);
235  } else {
236  delete this;
237  return new knumber_error(knumber_error::ERROR_POS_INFINITY);
238  }
239  }
240 
241  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
242  knumber_fraction f(p);
243  return div(&f);
244  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
245  knumber_float *f = new knumber_float(this);
246  delete this;
247  return f->div(p);
248  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
249  mpq_div(mpq_, mpq_, p->mpq_);
250  return this;
251  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
252 
253  if(p->sign() > 0) {
254  delete this;
255  return new knumber_integer(0);
256  } else if(p->sign() < 0) {
257  delete this;
258  return new knumber_integer(0);
259  }
260 
261  knumber_error *e = new knumber_error(p);
262  delete this;
263  return e;
264  }
265 
266  Q_ASSERT(0);
267  return 0;
268 }
269 
270 //------------------------------------------------------------------------------
271 // Name:
272 //------------------------------------------------------------------------------
273 knumber_base *knumber_fraction::mod(knumber_base *rhs) {
274 
275  if(rhs->is_zero()) {
276  delete this;
277  return new knumber_error(knumber_error::ERROR_UNDEFINED);
278  }
279 
280  // NOTE: we don't support modulus operations with non-integer operands
281  mpq_set_d(mpq_, 0);
282  return this;
283 }
284 
285 //------------------------------------------------------------------------------
286 // Name:
287 //------------------------------------------------------------------------------
288 knumber_base *knumber_fraction::bitwise_and(knumber_base *rhs) {
289 
290  Q_UNUSED(rhs);
291  delete this;
292  // NOTE: we don't support bitwise operations with non-integer operands
293  return new knumber_integer(0);
294 }
295 
296 //------------------------------------------------------------------------------
297 // Name:
298 //------------------------------------------------------------------------------
299 knumber_base *knumber_fraction::bitwise_xor(knumber_base *rhs) {
300 
301  Q_UNUSED(rhs);
302  delete this;
303  // NOTE: we don't support bitwise operations with non-integer operands
304  return new knumber_integer(0);
305 }
306 
307 //------------------------------------------------------------------------------
308 // Name:
309 //------------------------------------------------------------------------------
310 knumber_base *knumber_fraction::bitwise_or(knumber_base *rhs) {
311 
312  Q_UNUSED(rhs);
313  delete this;
314  // NOTE: we don't support bitwise operations with non-integer operands
315  return new knumber_integer(0);
316 }
317 
318 //------------------------------------------------------------------------------
319 // Name:
320 //------------------------------------------------------------------------------
321 knumber_base *knumber_fraction::bitwise_shift(knumber_base *rhs) {
322 
323  Q_UNUSED(rhs);
324  delete this;
325  // NOTE: we don't support bitwise operations with non-integer operands
326  return new knumber_error(knumber_error::ERROR_UNDEFINED);
327 }
328 
329 //------------------------------------------------------------------------------
330 // Name:
331 //------------------------------------------------------------------------------
332 knumber_base *knumber_fraction::neg() {
333  mpq_neg(mpq_, mpq_);
334  return this;
335 }
336 
337 //------------------------------------------------------------------------------
338 // Name:
339 //------------------------------------------------------------------------------
340 knumber_base *knumber_fraction::abs() {
341  mpq_abs(mpq_, mpq_);
342  return this;
343 }
344 
345 //------------------------------------------------------------------------------
346 // Name:
347 //------------------------------------------------------------------------------
348 knumber_base *knumber_fraction::cmp() {
349 
350  delete this;
351  return new knumber_error(knumber_error::ERROR_UNDEFINED);
352 }
353 
354 //------------------------------------------------------------------------------
355 // Name:
356 //------------------------------------------------------------------------------
357 knumber_base *knumber_fraction::sqrt() {
358 
359  if(sign() < 0) {
360  delete this;
361  return new knumber_error(knumber_error::ERROR_UNDEFINED);
362  }
363 
364  if(mpz_perfect_square_p(mpq_numref(mpq_)) && mpz_perfect_square_p(mpq_denref(mpq_))) {
365  mpz_t num;
366  mpz_t den;
367  mpz_init(num);
368  mpz_init(den);
369  mpq_get_num(num, mpq_);
370  mpq_get_den(den, mpq_);
371  mpz_sqrt(num, num);
372  mpz_sqrt(den, den);
373  mpq_set_num(mpq_, num);
374  mpq_set_den(mpq_, den);
375  mpq_canonicalize(mpq_);
376  mpz_clear(num);
377  mpz_clear(den);
378  return this;
379  } else {
380  knumber_float *f = new knumber_float(this);
381  delete this;
382  return f->sqrt();
383  }
384 }
385 
386 //------------------------------------------------------------------------------
387 // Name:
388 //------------------------------------------------------------------------------
389 knumber_base *knumber_fraction::cbrt() {
390 
391  // TODO: figure out how to properly use mpq_numref/mpq_denref here
392  mpz_t num;
393  mpz_t den;
394 
395  mpz_init(num);
396  mpz_init(den);
397 
398  mpq_get_num(num, mpq_);
399  mpq_get_den(den, mpq_);
400 
401  if(mpz_root(num, num, 3) && mpz_root(den, den, 3)) {
402  mpq_set_num(mpq_, num);
403  mpq_set_den(mpq_, den);
404  mpq_canonicalize(mpq_);
405  mpz_clear(num);
406  mpz_clear(den);
407  return this;
408  } else {
409  mpz_clear(num);
410  mpz_clear(den);
411  knumber_float *f = new knumber_float(this);
412  delete this;
413  return f->cbrt();
414  }
415 }
416 
417 //------------------------------------------------------------------------------
418 // Name:
419 //------------------------------------------------------------------------------
420 knumber_base *knumber_fraction::factorial() {
421 
422  if(sign() < 0) {
423  delete this;
424  return new knumber_error(knumber_error::ERROR_UNDEFINED);
425  }
426 
427  knumber_integer *i = new knumber_integer(this);
428  delete this;
429  return i->factorial();
430 }
431 
432 //------------------------------------------------------------------------------
433 // Name:
434 //------------------------------------------------------------------------------
435 knumber_base *knumber_fraction::pow(knumber_base *rhs) {
436 
437  // TODO: figure out how to properly use mpq_numref/mpq_denref here
438  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
439 
440  mpz_t num;
441  mpz_t den;
442 
443  mpz_init(num);
444  mpz_init(den);
445 
446  mpq_get_num(num, mpq_);
447  mpq_get_den(den, mpq_);
448 
449  mpz_pow_ui(num, num, mpz_get_ui(p->mpz_));
450  mpz_pow_ui(den, den, mpz_get_ui(p->mpz_));
451  mpq_set_num(mpq_, num);
452  mpq_set_den(mpq_, den);
453  mpq_canonicalize(mpq_);
454  mpz_clear(num);
455  mpz_clear(den);
456 
457  if(p->sign() < 0) {
458  return reciprocal();
459  } else {
460  return this;
461  }
462  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
463  Q_UNUSED(p);
464  knumber_float *f = new knumber_float(this);
465  delete this;
466  return f->pow(rhs);
467  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
468 
469  // ok, so if any part of the number is > 1,000,000, then we risk
470  // the pow function overflowing... so we'll just convert to float to be safe
471  // TODO: at some point, we should figure out exactly what the threashold is
472  // and if there is a better way to determine if the pow function will
473  // overflow.
474  if(mpz_cmpabs_ui(mpq_numref(mpq_), 1000000) > 0 || mpz_cmpabs_ui(mpq_denref(mpq_), 1000000) > 0 || mpz_cmpabs_ui(mpq_numref(p->mpq_), 1000000) > 0 || mpz_cmpabs_ui(mpq_denref(p->mpq_), 1000000) > 0) {
475  knumber_float *f = new knumber_float(this);
476  delete this;
477  return f->pow(rhs);
478  }
479 
480  mpz_t lhs_num;
481  mpz_t lhs_den;
482  mpz_t rhs_num;
483  mpz_t rhs_den;
484 
485  mpz_init(lhs_num);
486  mpz_init(lhs_den);
487  mpz_init(rhs_num);
488  mpz_init(rhs_den);
489 
490  mpq_get_num(lhs_num, mpq_);
491  mpq_get_den(lhs_den, mpq_);
492  mpq_get_num(rhs_num, p->mpq_);
493  mpq_get_den(rhs_den, p->mpq_);
494 
495  mpz_pow_ui(lhs_num, lhs_num, mpz_get_ui(rhs_num));
496  mpz_pow_ui(lhs_den, lhs_den, mpz_get_ui(rhs_num));
497 
498  if(mpz_sgn(lhs_num) < 0 && mpz_even_p(rhs_den)) {
499  mpz_clear(lhs_num);
500  mpz_clear(lhs_den);
501  mpz_clear(rhs_num);
502  mpz_clear(rhs_den);
503  delete this;
504  return new knumber_error(knumber_error::ERROR_UNDEFINED);
505  }
506 
507  if(mpz_sgn(lhs_den) < 0 && mpz_even_p(rhs_den)) {
508  mpz_clear(lhs_num);
509  mpz_clear(lhs_den);
510  mpz_clear(rhs_num);
511  mpz_clear(rhs_den);
512  delete this;
513  return new knumber_error(knumber_error::ERROR_UNDEFINED);
514  }
515 
516  const int n1 = mpz_root(lhs_num, lhs_num, mpz_get_ui(rhs_den));
517  const int n2 = mpz_root(lhs_den, lhs_den, mpz_get_ui(rhs_den));
518 
519  if(n1 && n2) {
520 
521  mpq_set_num(mpq_, lhs_num);
522  mpq_set_den(mpq_, lhs_den);
523  mpq_canonicalize(mpq_);
524  mpz_clear(lhs_num);
525  mpz_clear(lhs_den);
526  mpz_clear(rhs_num);
527  mpz_clear(rhs_den);
528 
529  if(p->sign() < 0) {
530  return reciprocal();
531  } else {
532  return this;
533  }
534  } else {
535  mpz_clear(lhs_num);
536  mpz_clear(lhs_den);
537  mpz_clear(rhs_num);
538  mpz_clear(rhs_den);
539  knumber_float *f = new knumber_float(this);
540  delete this;
541 
542  return f->pow(rhs);
543  }
544 
545  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
546  if(p->sign() > 0) {
547  knumber_error *e = new knumber_error(knumber_error::ERROR_POS_INFINITY);
548  delete this;
549  return e;
550  } else if(p->sign() < 0) {
551  knumber_integer *n = new knumber_integer(0);
552  delete this;
553  return n;
554  } else {
555  knumber_error *e = new knumber_error(knumber_error::ERROR_UNDEFINED);
556  delete this;
557  return e;
558  }
559  }
560 
561  Q_ASSERT(0);
562  return 0;
563 }
564 
565 //------------------------------------------------------------------------------
566 // Name:
567 //------------------------------------------------------------------------------
568 knumber_base *knumber_fraction::sin() {
569 
570  knumber_float *f = new knumber_float(this);
571  delete this;
572  return f->sin();
573 }
574 
575 //------------------------------------------------------------------------------
576 // Name:
577 //------------------------------------------------------------------------------
578 knumber_base *knumber_fraction::floor() {
579  knumber_float *f = new knumber_float(this);
580  delete this;
581  return f->floor();
582 }
583 
584 //------------------------------------------------------------------------------
585 // Name:
586 //------------------------------------------------------------------------------
587 knumber_base *knumber_fraction::ceil() {
588  knumber_float *f = new knumber_float(this);
589  delete this;
590  return f->ceil();
591 }
592 
593 //------------------------------------------------------------------------------
594 // Name:
595 //------------------------------------------------------------------------------
596 knumber_base *knumber_fraction::cos() {
597 
598  knumber_float *f = new knumber_float(this);
599  delete this;
600  return f->cos();
601 }
602 
603 //------------------------------------------------------------------------------
604 // Name:
605 //------------------------------------------------------------------------------
606 knumber_base *knumber_fraction::tgamma() {
607 
608  knumber_float *f = new knumber_float(this);
609  delete this;
610  return f->tgamma();
611 }
612 
613 //------------------------------------------------------------------------------
614 // Name:
615 //------------------------------------------------------------------------------
616 knumber_base *knumber_fraction::tan() {
617 
618  knumber_float *f = new knumber_float(this);
619  delete this;
620  return f->tan();
621 }
622 
623 //------------------------------------------------------------------------------
624 // Name:
625 //------------------------------------------------------------------------------
626 knumber_base *knumber_fraction::asin() {
627 
628  knumber_float *f = new knumber_float(this);
629  delete this;
630  return f->asin();
631 }
632 
633 //------------------------------------------------------------------------------
634 // Name:
635 //------------------------------------------------------------------------------
636 knumber_base *knumber_fraction::acos() {
637 
638  knumber_float *f = new knumber_float(this);
639  delete this;
640  return f->acos();
641 }
642 
643 //------------------------------------------------------------------------------
644 // Name:
645 //------------------------------------------------------------------------------
646 knumber_base *knumber_fraction::atan() {
647 
648  knumber_float *f = new knumber_float(this);
649  delete this;
650  return f->atan();
651 }
652 
653 //------------------------------------------------------------------------------
654 // Name:
655 //------------------------------------------------------------------------------
656 knumber_base *knumber_fraction::sinh() {
657  knumber_float *f = new knumber_float(this);
658  delete this;
659  return f->sinh();
660 }
661 
662 //------------------------------------------------------------------------------
663 // Name:
664 //------------------------------------------------------------------------------
665 knumber_base *knumber_fraction::cosh() {
666  knumber_float *f = new knumber_float(this);
667  delete this;
668  return f->cosh();
669 }
670 
671 //------------------------------------------------------------------------------
672 // Name:
673 //------------------------------------------------------------------------------
674 knumber_base *knumber_fraction::tanh() {
675  knumber_float *f = new knumber_float(this);
676  delete this;
677  return f->tanh();
678 }
679 
680 //------------------------------------------------------------------------------
681 // Name:
682 //------------------------------------------------------------------------------
683 knumber_base *knumber_fraction::asinh() {
684  knumber_float *f = new knumber_float(this);
685  delete this;
686  return f->asinh();
687 }
688 
689 //------------------------------------------------------------------------------
690 // Name:
691 //------------------------------------------------------------------------------
692 knumber_base *knumber_fraction::acosh() {
693  knumber_float *f = new knumber_float(this);
694  delete this;
695  return f->acosh();
696 }
697 
698 //------------------------------------------------------------------------------
699 // Name:
700 //------------------------------------------------------------------------------
701 knumber_base *knumber_fraction::atanh() {
702  knumber_float *f = new knumber_float(this);
703  delete this;
704  return f->atanh();
705 }
706 
707 //------------------------------------------------------------------------------
708 // Name:
709 //------------------------------------------------------------------------------
710 int knumber_fraction::compare(knumber_base *rhs) {
711 
712  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
713  knumber_fraction f(p);
714  return mpq_cmp(mpq_, f.mpq_);
715  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
716  knumber_float f(this);
717  return f.compare(p);
718  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
719  return mpq_cmp(mpq_, p->mpq_);
720  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
721  // NOTE: any number compared to NaN/Inf/-Inf always compares less
722  // at the moment
723  return -1;
724  }
725 
726  Q_ASSERT(0);
727  return 0;
728 }
729 
730 //------------------------------------------------------------------------------
731 // Name:
732 //------------------------------------------------------------------------------
733 QString knumber_fraction::toString(int precision) const {
734 
735 
736  if(knumber_fraction::default_fractional_output) {
737 
738  // TODO: figure out how to properly use mpq_numref/mpq_denref here
739 
740  knumber_integer integer_part(this);
741  if(split_off_integer_for_fraction_output && !integer_part.is_zero()) {
742 
743  mpz_t num;
744  mpz_init(num);
745  mpq_get_num(num, mpq_);
746 
747  knumber_integer integer_part_1(this);
748 
749  mpz_mul(integer_part.mpz_, integer_part.mpz_, mpq_denref(mpq_));
750  mpz_sub(num, num, integer_part.mpz_);
751 
752  if(mpz_sgn(num) < 0) {
753  mpz_neg(num, num);
754  }
755 
756  const size_t size = gmp_snprintf(NULL, 0, "%Zd %Zd/%Zd", integer_part_1.mpz_, num, mpq_denref(mpq_)) + 1;
757  QScopedArrayPointer<char> buf(new char[size]);
758  gmp_snprintf(&buf[0], size, "%Zd %Zd/%Zd", integer_part_1.mpz_, num, mpq_denref(mpq_));
759 
760  mpz_clear(num);
761 
762  return QLatin1String(&buf[0]);
763  } else {
764 
765  mpz_t num;
766  mpz_init(num);
767  mpq_get_num(num, mpq_);
768 
769  const size_t size = gmp_snprintf(NULL, 0, "%Zd/%Zd", num, mpq_denref(mpq_)) + 1;
770  QScopedArrayPointer<char> buf(new char[size]);
771  gmp_snprintf(&buf[0], size, "%Zd/%Zd", num, mpq_denref(mpq_));
772 
773  mpz_clear(num);
774 
775  return QLatin1String(&buf[0]);
776  }
777  } else {
778  return knumber_float(this).toString(precision);
779  }
780 }
781 
782 //------------------------------------------------------------------------------
783 // Name:
784 //------------------------------------------------------------------------------
785 bool knumber_fraction::is_zero() const {
786  return mpq_sgn(mpq_) == 0;
787 }
788 
789 //------------------------------------------------------------------------------
790 // Name:
791 //------------------------------------------------------------------------------
792 int knumber_fraction::sign() const {
793  return mpq_sgn(mpq_);
794 }
795 
796 //------------------------------------------------------------------------------
797 // Name:
798 //------------------------------------------------------------------------------
799 knumber_base *knumber_fraction::reciprocal() {
800 
801  mpq_inv(mpq_, mpq_);
802  return this;
803 }
804 
805 //------------------------------------------------------------------------------
806 // Name:
807 //------------------------------------------------------------------------------
808 knumber_integer *knumber_fraction::numerator() const {
809 
810  mpz_t num;
811  mpz_init(num);
812  mpq_get_num(num, mpq_);
813  knumber_integer *n = new knumber_integer(num);
814  mpz_clear(num);
815  return n;
816 }
817 
818 //------------------------------------------------------------------------------
819 // Name:
820 //------------------------------------------------------------------------------
821 knumber_integer *knumber_fraction::denominator() const {
822 
823  mpz_t den;
824  mpz_init(den);
825  mpq_get_den(den, mpq_);
826  knumber_integer *n = new knumber_integer(den);
827  mpz_clear(den);
828  return n;
829 }
830 
831 //------------------------------------------------------------------------------
832 // Name:
833 //------------------------------------------------------------------------------
834 knumber_base *knumber_fraction::log2() {
835  knumber_float *f = new knumber_float(this);
836  delete this;
837  return f->log2();
838 }
839 
840 //------------------------------------------------------------------------------
841 // Name:
842 //------------------------------------------------------------------------------
843 knumber_base *knumber_fraction::log10() {
844  knumber_float *f = new knumber_float(this);
845  delete this;
846  return f->log10();
847 }
848 
849 //------------------------------------------------------------------------------
850 // Name:
851 //------------------------------------------------------------------------------
852 knumber_base *knumber_fraction::ln() {
853  knumber_float *f = new knumber_float(this);
854  delete this;
855  return f->ln();
856 }
857 
858 //------------------------------------------------------------------------------
859 // Name:
860 //------------------------------------------------------------------------------
861 knumber_base *knumber_fraction::exp2() {
862  knumber_float *f = new knumber_float(this);
863  delete this;
864  return f->exp2();
865 }
866 
867 //------------------------------------------------------------------------------
868 // Name:
869 //------------------------------------------------------------------------------
870 knumber_base *knumber_fraction::exp10() {
871  knumber_float *f = new knumber_float(this);
872  delete this;
873  return f->exp10();
874 }
875 
876 //------------------------------------------------------------------------------
877 // Name:
878 //------------------------------------------------------------------------------
879 knumber_base *knumber_fraction::exp() {
880  knumber_float *f = new knumber_float(this);
881  delete this;
882  return f->exp();
883 }
884 
885 //------------------------------------------------------------------------------
886 // Name:
887 //------------------------------------------------------------------------------
888 quint64 knumber_fraction::toUint64() const {
889  return knumber_integer(this).toUint64();
890 }
891 
892 //------------------------------------------------------------------------------
893 // Name:
894 //------------------------------------------------------------------------------
895 qint64 knumber_fraction::toInt64() const {
896  return knumber_integer(this).toInt64();
897 }
898 
899 //------------------------------------------------------------------------------
900 // Name:
901 //------------------------------------------------------------------------------
902 knumber_base *knumber_fraction::bin(knumber_base *rhs) {
903  Q_UNUSED(rhs);
904  delete this;
905  return new knumber_error(knumber_error::ERROR_UNDEFINED);
906 
907 }
908 
909 }
detail::knumber_fraction::cos
virtual knumber_base * cos()
Definition: knumber_fraction.cpp:596
detail::knumber_fraction::exp10
virtual knumber_base * exp10()
Definition: knumber_fraction.cpp:870
detail::knumber_fraction::cmp
virtual knumber_base * cmp()
Definition: knumber_fraction.cpp:348
detail::knumber_fraction::split_off_integer_for_fraction_output
static bool split_off_integer_for_fraction_output
Definition: knumber_fraction.h:37
detail::knumber_float::cosh
virtual knumber_base * cosh()
Definition: knumber_float.cpp:647
detail::knumber_fraction::set_default_fractional_output
static void set_default_fractional_output(bool value)
Definition: knumber_fraction.cpp:43
detail::knumber_fraction::knumber_error
friend class knumber_error
Definition: knumber_fraction.h:30
detail::knumber_fraction::sin
virtual knumber_base * sin()
Definition: knumber_fraction.cpp:568
detail::knumber_float::floor
virtual knumber_base * floor()
Definition: knumber_float.cpp:463
detail::knumber_fraction::set_default_fractional_input
static void set_default_fractional_input(bool value)
Definition: knumber_fraction.cpp:36
detail::knumber_fraction::cosh
virtual knumber_base * cosh()
Definition: knumber_fraction.cpp:665
detail::knumber_fraction::asinh
virtual knumber_base * asinh()
Definition: knumber_fraction.cpp:683
detail::knumber_fraction::bitwise_or
virtual knumber_base * bitwise_or(knumber_base *rhs)
Definition: knumber_fraction.cpp:310
detail::knumber_float::tanh
virtual knumber_base * tanh()
Definition: knumber_float.cpp:664
detail::knumber_float::atanh
virtual knumber_base * atanh()
Definition: knumber_float.cpp:740
detail::knumber_fraction::cbrt
virtual knumber_base * cbrt()
Definition: knumber_fraction.cpp:389
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_fraction::reciprocal
virtual knumber_base * reciprocal()
Definition: knumber_fraction.cpp:799
detail::knumber_float::mul
virtual knumber_base * mul(knumber_base *rhs)
Definition: knumber_float.cpp:219
detail::knumber_fraction::tgamma
virtual knumber_base * tgamma()
Definition: knumber_fraction.cpp:606
detail::knumber_fraction::log2
virtual knumber_base * log2()
Definition: knumber_fraction.cpp:834
detail::knumber_fraction::div
virtual knumber_base * div(knumber_base *rhs)
Definition: knumber_fraction.cpp:229
detail::knumber_fraction::exp
virtual knumber_base * exp()
Definition: knumber_fraction.cpp:879
detail::knumber_fraction::exp2
virtual knumber_base * exp2()
Definition: knumber_fraction.cpp:861
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_fraction::ceil
virtual knumber_base * ceil()
Definition: knumber_fraction.cpp:587
detail::knumber_fraction::bitwise_and
virtual knumber_base * bitwise_and(knumber_base *rhs)
Definition: knumber_fraction.cpp:288
detail::knumber_fraction::mul
virtual knumber_base * mul(knumber_base *rhs)
Definition: knumber_fraction.cpp:191
detail::knumber_base::is_zero
virtual bool is_zero() const =0
detail::knumber_fraction::tanh
virtual knumber_base * tanh()
Definition: knumber_fraction.cpp:674
detail::knumber_float::sin
virtual knumber_base * sin()
Definition: knumber_float.cpp:439
detail::knumber_base
Definition: knumber_base.h:38
detail::knumber_fraction::tan
virtual knumber_base * tan()
Definition: knumber_fraction.cpp:616
detail::knumber_fraction
Definition: knumber_fraction.h:28
detail::knumber_fraction::floor
virtual knumber_base * floor()
Definition: knumber_fraction.cpp:578
detail::knumber_fraction::sub
virtual knumber_base * sub(knumber_base *rhs)
Definition: knumber_fraction.cpp:165
detail::knumber_fraction::is_integer
virtual bool is_integer() const
Definition: knumber_fraction.cpp:132
detail::knumber_float::ln
virtual knumber_base * ln()
Definition: knumber_float.cpp:920
detail::knumber_fraction::pow
virtual knumber_base * pow(knumber_base *rhs)
Definition: knumber_fraction.cpp:435
detail::knumber_float::tgamma
virtual knumber_base * tgamma()
Definition: knumber_float.cpp:681
detail::knumber_integer
Definition: knumber_integer.h:28
detail::knumber_fraction::atanh
virtual knumber_base * atanh()
Definition: knumber_fraction.cpp:701
detail::knumber_integer::is_zero
virtual bool is_zero() const
Definition: knumber_integer.cpp:759
detail::knumber_float::div
virtual knumber_base * div(knumber_base *rhs)
Definition: knumber_float.cpp:253
knumber_fraction.h
detail::knumber_fraction::mod
virtual knumber_base * mod(knumber_base *rhs)
Definition: knumber_fraction.cpp:273
detail::knumber_fraction::is_zero
virtual bool is_zero() const
Definition: knumber_fraction.cpp:785
QString
detail::knumber_float::sub
virtual knumber_base * sub(knumber_base *rhs)
Definition: knumber_float.cpp:195
detail::knumber_float::asinh
virtual knumber_base * asinh()
Definition: knumber_float.cpp:706
detail::knumber_float::exp2
virtual knumber_base * exp2()
Definition: knumber_float.cpp:942
detail::knumber_fraction::add
virtual knumber_base * add(knumber_base *rhs)
Definition: knumber_fraction.cpp:139
detail::knumber_float::acos
virtual knumber_base * acos()
Definition: knumber_float.cpp:579
detail::knumber_fraction::ln
virtual knumber_base * ln()
Definition: knumber_fraction.cpp:852
detail::knumber_fraction::toUint64
virtual quint64 toUint64() const
Definition: knumber_fraction.cpp:888
detail::knumber_fraction::set_split_off_integer_for_fraction_output
static void set_split_off_integer_for_fraction_output(bool value)
Definition: knumber_fraction.cpp:50
detail::knumber_float::exp
virtual knumber_base * exp()
Definition: knumber_float.cpp:986
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_fraction::log10
virtual knumber_base * log10()
Definition: knumber_fraction.cpp:843
detail::knumber_fraction::acos
virtual knumber_base * acos()
Definition: knumber_fraction.cpp:636
detail::knumber_fraction::bitwise_xor
virtual knumber_base * bitwise_xor(knumber_base *rhs)
Definition: knumber_fraction.cpp:299
detail::knumber_fraction::sign
virtual int sign() const
Definition: knumber_fraction.cpp:792
detail::knumber_error::ERROR_POS_INFINITY
Definition: knumber_error.h:37
detail::knumber_float::atan
virtual knumber_base * atan()
Definition: knumber_float.cpp:606
detail::knumber_fraction::bin
virtual knumber_base * bin(knumber_base *rhs)
Definition: knumber_fraction.cpp:902
QLatin1String
detail::knumber_fraction::toString
virtual QString toString(int precision) const
Definition: knumber_fraction.cpp:733
detail::knumber_float::cos
virtual knumber_base * cos()
Definition: knumber_float.cpp:506
detail::knumber_fraction::default_fractional_input
static bool default_fractional_input
Definition: knumber_fraction.h:35
detail::knumber_float::asin
virtual knumber_base * asin()
Definition: knumber_float.cpp:552
detail::knumber_float
Definition: knumber_float.h:28
detail::knumber_fraction::clone
virtual knumber_base * clone()
Definition: knumber_fraction.cpp:118
knumber_error.h
QScopedArrayPointer
detail::knumber_float::compare
virtual int compare(knumber_base *rhs)
Definition: knumber_float.cpp:795
detail::knumber_fraction::knumber_fraction
knumber_fraction(const QString &s)
Definition: knumber_fraction.cpp:57
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::sinh
virtual knumber_base * sinh()
Definition: knumber_float.cpp:629
detail::knumber_fraction::sqrt
virtual knumber_base * sqrt()
Definition: knumber_fraction.cpp:357
detail::knumber_fraction::~knumber_fraction
virtual ~knumber_fraction()
Definition: knumber_fraction.cpp:125
detail::knumber_fraction::default_fractional_output
static bool default_fractional_output
Definition: knumber_fraction.h:36
detail::knumber_fraction::abs
virtual knumber_base * abs()
Definition: knumber_fraction.cpp:340
detail::knumber_float::log2
virtual knumber_base * log2()
Definition: knumber_float.cpp:876
detail::knumber_error::ERROR_UNDEFINED
Definition: knumber_error.h:36
detail::knumber_fraction::neg
virtual knumber_base * neg()
Definition: knumber_fraction.cpp:332
detail::knumber_fraction::compare
virtual int compare(knumber_base *rhs)
Definition: knumber_fraction.cpp:710
detail::knumber_integer::factorial
virtual knumber_base * factorial()
Definition: knumber_integer.cpp:660
detail::knumber_fraction::acosh
virtual knumber_base * acosh()
Definition: knumber_fraction.cpp:692
detail::knumber_fraction::asin
virtual knumber_base * asin()
Definition: knumber_fraction.cpp:626
detail::knumber_fraction::toInt64
virtual qint64 toInt64() const
Definition: knumber_fraction.cpp:895
detail::knumber_fraction::knumber_integer
friend class knumber_integer
Definition: knumber_fraction.h:31
detail::knumber_fraction::factorial
virtual knumber_base * factorial()
Definition: knumber_fraction.cpp:420
detail::knumber_fraction::atan
virtual knumber_base * atan()
Definition: knumber_fraction.cpp:646
detail::knumber_fraction::sinh
virtual knumber_base * sinh()
Definition: knumber_fraction.cpp:656
detail::knumber_fraction::bitwise_shift
virtual knumber_base * bitwise_shift(knumber_base *rhs)
Definition: knumber_fraction.cpp:321
detail::knumber_error::neg
virtual knumber_base * neg()
Definition: knumber_error.cpp:300
QString::toAscii
QByteArray toAscii() const
detail::knumber_fraction::knumber_float
friend class knumber_float
Definition: knumber_fraction.h:32
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