• 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_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_integer(0);
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::cos() {
579 
580  knumber_float *f = new knumber_float(this);
581  delete this;
582  return f->cos();
583 }
584 
585 //------------------------------------------------------------------------------
586 // Name:
587 //------------------------------------------------------------------------------
588 knumber_base *knumber_fraction::tan() {
589 
590  knumber_float *f = new knumber_float(this);
591  delete this;
592  return f->tan();
593 }
594 
595 //------------------------------------------------------------------------------
596 // Name:
597 //------------------------------------------------------------------------------
598 knumber_base *knumber_fraction::asin() {
599 
600  knumber_float *f = new knumber_float(this);
601  delete this;
602  return f->asin();
603 }
604 
605 //------------------------------------------------------------------------------
606 // Name:
607 //------------------------------------------------------------------------------
608 knumber_base *knumber_fraction::acos() {
609 
610  knumber_float *f = new knumber_float(this);
611  delete this;
612  return f->acos();
613 }
614 
615 //------------------------------------------------------------------------------
616 // Name:
617 //------------------------------------------------------------------------------
618 knumber_base *knumber_fraction::atan() {
619 
620  knumber_float *f = new knumber_float(this);
621  delete this;
622  return f->atan();
623 }
624 
625 //------------------------------------------------------------------------------
626 // Name:
627 //------------------------------------------------------------------------------
628 knumber_base *knumber_fraction::sinh() {
629  knumber_float *f = new knumber_float(this);
630  delete this;
631  return f->sinh();
632 }
633 
634 //------------------------------------------------------------------------------
635 // Name:
636 //------------------------------------------------------------------------------
637 knumber_base *knumber_fraction::cosh() {
638  knumber_float *f = new knumber_float(this);
639  delete this;
640  return f->cosh();
641 }
642 
643 //------------------------------------------------------------------------------
644 // Name:
645 //------------------------------------------------------------------------------
646 knumber_base *knumber_fraction::tanh() {
647  knumber_float *f = new knumber_float(this);
648  delete this;
649  return f->tanh();
650 }
651 
652 //------------------------------------------------------------------------------
653 // Name:
654 //------------------------------------------------------------------------------
655 knumber_base *knumber_fraction::asinh() {
656  knumber_float *f = new knumber_float(this);
657  delete this;
658  return f->asinh();
659 }
660 
661 //------------------------------------------------------------------------------
662 // Name:
663 //------------------------------------------------------------------------------
664 knumber_base *knumber_fraction::acosh() {
665  knumber_float *f = new knumber_float(this);
666  delete this;
667  return f->acosh();
668 }
669 
670 //------------------------------------------------------------------------------
671 // Name:
672 //------------------------------------------------------------------------------
673 knumber_base *knumber_fraction::atanh() {
674  knumber_float *f = new knumber_float(this);
675  delete this;
676  return f->atanh();
677 }
678 
679 //------------------------------------------------------------------------------
680 // Name:
681 //------------------------------------------------------------------------------
682 int knumber_fraction::compare(knumber_base *rhs) {
683 
684  if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
685  knumber_fraction f(p);
686  return mpq_cmp(mpq_, f.mpq_);
687  } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
688  knumber_float f(this);
689  return f.compare(p);
690  } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
691  return mpq_cmp(mpq_, p->mpq_);
692  } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
693  // NOTE: any number compared to NaN/Inf/-Inf always compares less
694  // at the moment
695  return -1;
696  }
697 
698  Q_ASSERT(0);
699  return 0;
700 }
701 
702 //------------------------------------------------------------------------------
703 // Name:
704 //------------------------------------------------------------------------------
705 QString knumber_fraction::toString(int precision) const {
706 
707 
708  if(knumber_fraction::default_fractional_output) {
709 
710  // TODO: figure out how to properly use mpq_numref/mpq_denref here
711 
712  knumber_integer integer_part(this);
713  if(split_off_integer_for_fraction_output && !integer_part.is_zero()) {
714 
715  mpz_t num;
716  mpz_init(num);
717  mpq_get_num(num, mpq_);
718 
719  knumber_integer integer_part_1(this);
720 
721  mpz_mul(integer_part.mpz_, integer_part.mpz_, mpq_denref(mpq_));
722  mpz_sub(num, num, integer_part.mpz_);
723 
724  if(mpz_sgn(num) < 0) {
725  mpz_neg(num, num);
726  }
727 
728  const size_t size = gmp_snprintf(NULL, 0, "%Zd %Zd/%Zd", integer_part_1.mpz_, num, mpq_denref(mpq_)) + 1;
729  QScopedArrayPointer<char> buf(new char[size]);
730  gmp_snprintf(&buf[0], size, "%Zd %Zd/%Zd", integer_part_1.mpz_, num, mpq_denref(mpq_));
731 
732  mpz_clear(num);
733 
734  return QLatin1String(&buf[0]);
735  } else {
736 
737  mpz_t num;
738  mpz_init(num);
739  mpq_get_num(num, mpq_);
740 
741  const size_t size = gmp_snprintf(NULL, 0, "%Zd/%Zd", num, mpq_denref(mpq_)) + 1;
742  QScopedArrayPointer<char> buf(new char[size]);
743  gmp_snprintf(&buf[0], size, "%Zd/%Zd", num, mpq_denref(mpq_));
744 
745  mpz_clear(num);
746 
747  return QLatin1String(&buf[0]);
748  }
749  } else {
750  return knumber_float(this).toString(precision);
751  }
752 }
753 
754 //------------------------------------------------------------------------------
755 // Name:
756 //------------------------------------------------------------------------------
757 bool knumber_fraction::is_zero() const {
758  return mpq_sgn(mpq_) == 0;
759 }
760 
761 //------------------------------------------------------------------------------
762 // Name:
763 //------------------------------------------------------------------------------
764 int knumber_fraction::sign() const {
765  return mpq_sgn(mpq_);
766 }
767 
768 //------------------------------------------------------------------------------
769 // Name:
770 //------------------------------------------------------------------------------
771 knumber_base *knumber_fraction::reciprocal() {
772 
773  mpq_inv(mpq_, mpq_);
774  return this;
775 }
776 
777 //------------------------------------------------------------------------------
778 // Name:
779 //------------------------------------------------------------------------------
780 knumber_integer *knumber_fraction::numerator() const {
781 
782  mpz_t num;
783  mpz_init(num);
784  mpq_get_num(num, mpq_);
785  knumber_integer *n = new knumber_integer(num);
786  mpz_clear(num);
787  return n;
788 }
789 
790 //------------------------------------------------------------------------------
791 // Name:
792 //------------------------------------------------------------------------------
793 knumber_integer *knumber_fraction::denominator() const {
794 
795  mpz_t den;
796  mpz_init(den);
797  mpq_get_den(den, mpq_);
798  knumber_integer *n = new knumber_integer(den);
799  mpz_clear(den);
800  return n;
801 }
802 
803 //------------------------------------------------------------------------------
804 // Name:
805 //------------------------------------------------------------------------------
806 knumber_base *knumber_fraction::log2() {
807  knumber_float *f = new knumber_float(this);
808  delete this;
809  return f->log2();
810 }
811 
812 //------------------------------------------------------------------------------
813 // Name:
814 //------------------------------------------------------------------------------
815 knumber_base *knumber_fraction::log10() {
816  knumber_float *f = new knumber_float(this);
817  delete this;
818  return f->log10();
819 }
820 
821 //------------------------------------------------------------------------------
822 // Name:
823 //------------------------------------------------------------------------------
824 knumber_base *knumber_fraction::ln() {
825  knumber_float *f = new knumber_float(this);
826  delete this;
827  return f->ln();
828 }
829 
830 //------------------------------------------------------------------------------
831 // Name:
832 //------------------------------------------------------------------------------
833 knumber_base *knumber_fraction::exp2() {
834  knumber_float *f = new knumber_float(this);
835  delete this;
836  return f->exp2();
837 }
838 
839 //------------------------------------------------------------------------------
840 // Name:
841 //------------------------------------------------------------------------------
842 knumber_base *knumber_fraction::exp10() {
843  knumber_float *f = new knumber_float(this);
844  delete this;
845  return f->exp10();
846 }
847 
848 //------------------------------------------------------------------------------
849 // Name:
850 //------------------------------------------------------------------------------
851 knumber_base *knumber_fraction::exp() {
852  knumber_float *f = new knumber_float(this);
853  delete this;
854  return f->exp();
855 }
856 
857 //------------------------------------------------------------------------------
858 // Name:
859 //------------------------------------------------------------------------------
860 quint64 knumber_fraction::toUint64() const {
861  return knumber_integer(this).toUint64();
862 }
863 
864 //------------------------------------------------------------------------------
865 // Name:
866 //------------------------------------------------------------------------------
867 qint64 knumber_fraction::toInt64() const {
868  return knumber_integer(this).toInt64();
869 }
870 
871 //------------------------------------------------------------------------------
872 // Name:
873 //------------------------------------------------------------------------------
874 knumber_base *knumber_fraction::bin(knumber_base *rhs) {
875  Q_UNUSED(rhs);
876  delete this;
877  return new knumber_error(knumber_error::ERROR_UNDEFINED);
878 
879 }
880 
881 }
detail::knumber_fraction::cos
virtual knumber_base * cos()
Definition: knumber_fraction.cpp:578
detail::knumber_fraction::exp10
virtual knumber_base * exp10()
Definition: knumber_fraction.cpp:842
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:603
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_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:637
detail::knumber_fraction::asinh
virtual knumber_base * asinh()
Definition: knumber_fraction.cpp:655
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:620
detail::knumber_float::atanh
virtual knumber_base * atanh()
Definition: knumber_float.cpp:671
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: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_fraction::reciprocal
virtual knumber_base * reciprocal()
Definition: knumber_fraction.cpp:771
detail::knumber_float::mul
virtual knumber_base * mul(knumber_base *rhs)
Definition: knumber_float.cpp:219
detail::knumber_fraction::log2
virtual knumber_base * log2()
Definition: knumber_fraction.cpp:806
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:851
detail::knumber_fraction::exp2
virtual knumber_base * exp2()
Definition: knumber_fraction.cpp:833
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_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:646
detail::knumber_float::sin
virtual knumber_base * sin()
Definition: knumber_float.cpp:438
detail::knumber_base
Definition: knumber_base.h:38
detail::knumber_fraction::tan
virtual knumber_base * tan()
Definition: knumber_fraction.cpp:588
detail::knumber_fraction
Definition: knumber_fraction.h:28
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:851
detail::knumber_fraction::pow
virtual knumber_base * pow(knumber_base *rhs)
Definition: knumber_fraction.cpp:435
detail::knumber_integer
Definition: knumber_integer.h:28
detail::knumber_fraction::atanh
virtual knumber_base * atanh()
Definition: knumber_fraction.cpp:673
detail::knumber_integer::is_zero
virtual bool is_zero() const
Definition: knumber_integer.cpp:749
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:757
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:637
detail::knumber_float::exp2
virtual knumber_base * exp2()
Definition: knumber_float.cpp:873
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:535
detail::knumber_fraction::ln
virtual knumber_base * ln()
Definition: knumber_fraction.cpp:824
detail::knumber_fraction::toUint64
virtual quint64 toUint64() const
Definition: knumber_fraction.cpp:860
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:917
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_fraction::log10
virtual knumber_base * log10()
Definition: knumber_fraction.cpp:815
detail::knumber_fraction::acos
virtual knumber_base * acos()
Definition: knumber_fraction.cpp:608
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:764
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_fraction::bin
virtual knumber_base * bin(knumber_base *rhs)
Definition: knumber_fraction.cpp:874
detail::knumber_fraction::toString
virtual QString toString(int precision) const
Definition: knumber_fraction.cpp:705
detail::knumber_float::cos
virtual knumber_base * cos()
Definition: knumber_float.cpp:462
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:508
detail::knumber_float
Definition: knumber_float.h:28
detail::knumber_fraction::clone
virtual knumber_base * clone()
Definition: knumber_fraction.cpp:118
knumber_error.h
detail::knumber_float::compare
virtual int compare(knumber_base *rhs)
Definition: knumber_float.cpp:726
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::sinh
virtual knumber_base * sinh()
Definition: knumber_float.cpp:585
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:807
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:682
detail::knumber_integer::factorial
virtual knumber_base * factorial()
Definition: knumber_integer.cpp:650
detail::knumber_fraction::acosh
virtual knumber_base * acosh()
Definition: knumber_fraction.cpp:664
detail::knumber_fraction::asin
virtual knumber_base * asin()
Definition: knumber_fraction.cpp:598
detail::knumber_fraction::toInt64
virtual qint64 toInt64() const
Definition: knumber_fraction.cpp:867
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:618
detail::knumber_fraction::sinh
virtual knumber_base * sinh()
Definition: knumber_fraction.cpp:628
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
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-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