31 KNumber const KNumber::MinusOne(-1);
32 KNumber const KNumber::Pi(
"3.141592653589793238462643383279502884197169" 33 "39937510582097494459230781640628620899862803" 35 KNumber const KNumber::Euler(
"2.718281828459045235360287471352662497757" 36 "24709369995957496696762772407663035354759" 37 "4571382178525166427");
38 KNumber const KNumber::NotDefined(
"nan");
40 bool KNumber::_float_output =
false;
41 bool KNumber::_fraction_input =
false;
42 bool KNumber::_splitoffinteger_output =
false;
44 KNumber::KNumber(
signed int num)
46 _num =
new _knuminteger(num);
49 KNumber::KNumber(
unsigned int num)
51 _num =
new _knuminteger(num);
54 KNumber::KNumber(
signed long int num)
56 _num =
new _knuminteger(num);
59 KNumber::KNumber(
unsigned long int num)
61 _num =
new _knuminteger(num);
64 KNumber::KNumber(
unsigned long long int num)
66 _num =
new _knuminteger(num);
69 KNumber::KNumber(
double num)
71 if ( isinf(num) ) _num =
new _knumerror( _knumber::Infinity );
72 else if ( isnan(num) ) _num =
new _knumerror( _knumber::UndefinedNumber );
73 else _num =
new _knumfloat(num);
77 KNumber::KNumber(
KNumber const & num)
81 _num =
new _knumerror(*(num._num));
84 _num =
new _knuminteger(*(num._num));
87 _num =
new _knumfraction(*(num._num));
90 _num =
new _knumfloat(*(num._num));
96 KNumber::KNumber(TQString
const & num)
98 if (TQRegExp(
"^(inf|-inf|nan)$").exactMatch(num))
99 _num =
new _knumerror(num);
100 else if (TQRegExp(
"^[+-]?\\d+$").exactMatch(num))
101 _num =
new _knuminteger(num);
102 else if (TQRegExp(
"^[+-]?\\d+/\\d+$").exactMatch(num)) {
103 _num =
new _knumfraction(num);
106 else if (TQRegExp(
"^[+-]?\\d+(\\.\\d*)?(e[+-]?\\d+)?$").exactMatch(num))
107 if (_fraction_input ==
true) {
108 _num =
new _knumfraction(num);
111 _num =
new _knumfloat(num);
113 _num =
new _knumerror(
"nan");
118 if(dynamic_cast<_knumerror *>(_num))
120 if(dynamic_cast<_knuminteger *>(_num))
122 if(dynamic_cast<_knumfraction *>(_num))
124 if(dynamic_cast<_knumfloat *>(_num))
134 void KNumber::simplifyRational(
void)
136 if (
type() != FractionType)
139 _knumfraction *tmp_num =
dynamic_cast<_knumfraction *
>(_num);
141 if (tmp_num->isInteger()) {
142 _knumber *tmp_num2 = tmp_num->intPart();
159 _num =
new _knumerror();
162 _num =
new _knuminteger();
165 _num =
new _knumfraction();
168 _num =
new _knumfloat();
172 _num->copy(*(num._num));
183 switch(tmp_num.
type()) {
185 _num =
new _knumerror();
188 _num =
new _knuminteger();
191 _num =
new _knumfraction();
194 _num =
new _knumfloat();
198 _num->copy(*(tmp_num._num));
209 switch(tmp_num.
type()) {
211 _num =
new _knumerror();
214 _num =
new _knuminteger();
217 _num =
new _knumfraction();
220 _num =
new _knumfloat();
224 _num->copy(*(tmp_num._num));
230 static void _inc_by_one(TQString &str,
int position)
232 for (
int i = position; i >= 0; i--)
234 char last_char = str[i].latin1();
266 if (i == 0) str.prepend(
'1');
276 static void _round(TQString &str,
int precision)
278 int decimalSymbolPos = str.find(
'.');
280 if (decimalSymbolPos == -1)
281 if (precision == 0)
return;
282 else if (precision > 0)
285 decimalSymbolPos = str.length() - 1;
289 str.append(TQString().fill(
'0', precision));
292 char last_char = str[decimalSymbolPos + precision + 1].latin1();
308 _inc_by_one(str, decimalSymbolPos + precision);
314 decimalSymbolPos = str.find(
'.');
315 str.truncate(decimalSymbolPos + precision + 1);
318 if (precision == 0) str = str.section(
'.', 0, 0);
321 static TQString roundNumber(
const TQString &numStr,
int precision)
323 TQString tmpString = numStr;
325 ! TQRegExp(
"^[+-]?\\d+(\\.\\d+)*(e[+-]?\\d+)?$").exactMatch(tmpString))
330 bool neg = (tmpString[0] ==
'-');
331 if (neg || tmpString[0] ==
'+') tmpString.remove(0, 1);
335 TQString mantString = tmpString.section(
'e', 0, 0,
336 TQString::SectionCaseInsensitiveSeps);
337 TQString expString = tmpString.section(
'e', 1, 1,
338 TQString::SectionCaseInsensitiveSeps |
339 TQString::SectionIncludeLeadingSep);
340 if (expString.length() == 1) expString = TQString();
343 _round(mantString, precision);
345 if(neg) mantString.prepend(
'-');
347 return mantString + expString;
360 bool tmp_bool = _fraction_input;
361 _fraction_input =
false;
363 _fraction_input = tmp_bool;
365 tmp_str = TQString(_num->ascii());
369 bool tmp_bool = _fraction_input;
370 _fraction_input =
false;
372 _fraction_input = tmp_bool;
374 if(_splitoffinteger_output) {
377 if (int_part == Zero)
378 tmp_str = TQString(_num->ascii());
379 else if (int_part < Zero)
380 tmp_str = int_part.
toTQString() +
" " + (int_part - *
this)._num->ascii();
382 tmp_str = int_part.
toTQString() +
" " + (*
this - int_part)._num->ascii();
384 tmp_str = TQString(_num->ascii());
386 if (width > 0 && tmp_str.length() > width) {
388 bool tmp_bool = _fraction_input;
389 _fraction_input =
false;
391 _fraction_input = tmp_bool;
398 tmp_str = TQString(_num->ascii(width));
401 tmp_str = TQString(_num->ascii(3*mpf_get_default_prec()/10));
404 return TQString(_num->ascii());
408 return roundNumber(tmp_str, prec);
415 _float_output = flag;
420 _fraction_input = flag;
425 _splitoffinteger_output = flag;
431 unsigned long int bin_prec =
static_cast<unsigned long int> 432 (double(prec) * M_LN10 / M_LN2 + 1);
434 mpf_set_default_prec(bin_prec);
442 tmp_num._num = _num->abs();
452 tmp_num._num = _num->cbrt();
462 tmp_num._num = _num->sqrt();
471 tmp_num._num = _num->intPart();
493 else if (exp < Zero) {
497 tmp_num._num = _num->power(*(tmp_num2._num));
504 tmp_num._num = _num->power(*(exp._num));
511 KNumber const KNumber::operator-(
void)
const 516 tmp_num._num = _num->change_sign();
526 tmp_num._num = _num->add(*arg2._num);
528 tmp_num.simplifyRational();
535 return *
this + (-arg2);
543 tmp_num._num = _num->multiply(*arg2._num);
545 tmp_num.simplifyRational();
555 tmp_num._num = _num->divide(*arg2._num);
557 tmp_num.simplifyRational();
565 if (
type() != IntegerType || arg2.
type() != IntegerType)
571 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
572 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
574 tmp_num._num = tmp_arg1->mod(*tmp_arg2);
581 if (
type() != IntegerType || arg2.
type() != IntegerType)
587 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
588 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
590 tmp_num._num = tmp_arg1->intAnd(*tmp_arg2);
598 if (
type() != IntegerType || arg2.
type() != IntegerType)
604 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
605 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
607 tmp_num._num = tmp_arg1->intOr(*tmp_arg2);
615 if (
type() != IntegerType || arg2.
type() != IntegerType)
618 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
619 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
623 tmp_num._num = tmp_arg1->shift(*tmp_arg2);
630 if (
type() != IntegerType || arg2.
type() != IntegerType)
635 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
636 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(tmp_num._num);
639 delete tmp_num2._num;
640 tmp_num2._num = tmp_arg1->shift(*tmp_arg2);
647 KNumber::operator bool(
void)
const 654 KNumber::operator
signed long int(
void)
const 656 return static_cast<signed long int>(*_num);
659 KNumber::operator
unsigned long int(
void)
const 661 return static_cast<unsigned long int>(*_num);
664 KNumber::operator
unsigned long long int(
void)
const 666 #if SIZEOF_UNSIGNED_LONG == 8 667 return static_cast<unsigned long int>(*this);
668 #elif SIZEOF_UNSIGNED_LONG == 4 670 unsigned long long int tmp_num2 =
static_cast<unsigned long int>(tmp_num1) +
671 (static_cast<unsigned long long int>(
672 static_cast<unsigned long int>(tmp_num1 >>
KNumber(
"32"))) << 32) ;
674 #warning the cast operator from KNumber to unsigned long long int is probably buggy, when a sign is involved 678 return static_cast<unsigned long long int> (-
static_cast<signed long long int>(tmp_num2));
680 #error "SIZEOF_UNSIGNED_LONG is a unhandled case" 684 KNumber::operator double(
void)
const 686 return static_cast<double>(*_num);
689 int const KNumber::compare(
KNumber const & arg2)
const 691 return _num->compare(*arg2._num);
NumType type(void) const
Returns the type of the number, as explained in KNumber::NumType.
static void setDefaultFractionalInput(bool flag)
Set whether a number constructed from a TQString should be initialized as a fraction or as a float...
KNumber const sqrt(void) const
Compute the square root.
static void setDefaultFloatOutput(bool flag)
Set whether the output of numbers (with KNumber::toTQString) should happen as floating point numbers ...
TQString const toTQString(int width=-1, int prec=-1) const
Return a TQString representing the KNumber.
static void setSplitoffIntegerForFractionOutput(bool flag)
What a terrible method name!! When displaying a fraction, the default mode gives "nomin/denom".
KNumber const cbrt(void) const
Compute the cube root.
KNumber const integerPart(void) const
Truncates a KNumber to its integer type returning a number of type NumType::IntegerType.
KNumber const abs(void) const
Compute the absolute value, i.e.
Class that provides arbitrary precision numbers.
NumType
KNumber tries to provide transparent access to the following type of numbers:
static void setDefaultFloatPrecision(unsigned int prec)
Set the default precision to be at least prec (decimal) digits.