32 KNumber const KNumber::MinusOne(-1);
33 KNumber const KNumber::Pi(
"3.141592653589793238462643383279502884197169" 34 "39937510582097494459230781640628620899862803" 36 KNumber const KNumber::Euler(
"2.718281828459045235360287471352662497757" 37 "24709369995957496696762772407663035354759" 38 "4571382178525166427");
39 KNumber const KNumber::NotDefined(
"nan");
41 bool KNumber::_float_output =
false;
42 bool KNumber::_fraction_input =
false;
43 bool KNumber::_splitoffinteger_output =
false;
45 KNumber::KNumber(
signed int num)
47 _num =
new _knuminteger(num);
50 KNumber::KNumber(
unsigned int num)
52 _num =
new _knuminteger(num);
55 KNumber::KNumber(
signed long int num)
57 _num =
new _knuminteger(num);
60 KNumber::KNumber(
unsigned long int num)
62 _num =
new _knuminteger(num);
65 KNumber::KNumber(
unsigned long long int num)
67 _num =
new _knuminteger(num);
70 KNumber::KNumber(
double num)
72 if ( isinf(num) ) _num =
new _knumerror( _knumber::Infinity );
73 else if ( isnan(num) ) _num =
new _knumerror( _knumber::UndefinedNumber );
74 else _num =
new _knumfloat(num);
78 KNumber::KNumber(
KNumber const & num)
82 _num =
new _knumerror(*(num._num));
85 _num =
new _knuminteger(*(num._num));
88 _num =
new _knumfraction(*(num._num));
91 _num =
new _knumfloat(*(num._num));
97 KNumber::KNumber(TQString
const & num)
99 if (TQRegExp(
"^(inf|-inf|nan)$").exactMatch(num))
100 _num =
new _knumerror(num);
101 else if (TQRegExp(
"^[+-]?\\d+$").exactMatch(num))
102 _num =
new _knuminteger(num);
103 else if (TQRegExp(
"^[+-]?\\d+/\\d+$").exactMatch(num)) {
104 _num =
new _knumfraction(num);
107 else if (TQRegExp(
"^[+-]?\\d+(\\.\\d*)?(e[+-]?\\d+)?$").exactMatch(num))
108 if (_fraction_input ==
true) {
109 _num =
new _knumfraction(num);
112 _num =
new _knumfloat(num);
114 _num =
new _knumerror(
"nan");
119 if(dynamic_cast<_knumerror *>(_num))
121 if(dynamic_cast<_knuminteger *>(_num))
123 if(dynamic_cast<_knumfraction *>(_num))
125 if(dynamic_cast<_knumfloat *>(_num))
135 void KNumber::simplifyRational(
void)
137 if (
type() != FractionType)
140 _knumfraction *tmp_num =
dynamic_cast<_knumfraction *
>(_num);
142 if (tmp_num->isInteger()) {
143 _knumber *tmp_num2 = tmp_num->intPart();
160 _num =
new _knumerror();
163 _num =
new _knuminteger();
166 _num =
new _knumfraction();
169 _num =
new _knumfloat();
173 _num->copy(*(num._num));
184 switch(tmp_num.
type()) {
186 _num =
new _knumerror();
189 _num =
new _knuminteger();
192 _num =
new _knumfraction();
195 _num =
new _knumfloat();
199 _num->copy(*(tmp_num._num));
210 switch(tmp_num.
type()) {
212 _num =
new _knumerror();
215 _num =
new _knuminteger();
218 _num =
new _knumfraction();
221 _num =
new _knumfloat();
225 _num->copy(*(tmp_num._num));
231 static void _inc_by_one(TQString &str,
int position)
233 for (
int i = position; i >= 0; i--)
235 char last_char = str[i].latin1();
267 if (i == 0) str.prepend(
'1');
277 static void _round(TQString &str,
int precision)
279 int decimalSymbolPos = str.find(
'.');
281 if (decimalSymbolPos == -1)
282 if (precision == 0)
return;
283 else if (precision > 0)
286 decimalSymbolPos = str.length() - 1;
290 str.append(TQString().fill(
'0', precision));
293 char last_char = str[decimalSymbolPos + precision + 1].latin1();
309 _inc_by_one(str, decimalSymbolPos + precision);
315 decimalSymbolPos = str.find(
'.');
316 str.truncate(decimalSymbolPos + precision + 1);
319 if (precision == 0) str = str.section(
'.', 0, 0);
322 static TQString roundNumber(
const TQString &numStr,
int precision)
324 TQString tmpString = numStr;
326 ! TQRegExp(
"^[+-]?\\d+(\\.\\d+)*(e[+-]?\\d+)?$").exactMatch(tmpString))
331 bool neg = (tmpString[0] ==
'-');
332 if (neg || tmpString[0] ==
'+') tmpString.remove(0, 1);
336 TQString mantString = tmpString.section(
'e', 0, 0,
337 TQString::SectionCaseInsensitiveSeps);
338 TQString expString = tmpString.section(
'e', 1, 1,
339 TQString::SectionCaseInsensitiveSeps |
340 TQString::SectionIncludeLeadingSep);
341 if (expString.length() == 1) expString = TQString();
344 _round(mantString, precision);
346 if(neg) mantString.prepend(
'-');
348 return mantString + expString;
361 bool tmp_bool = _fraction_input;
362 _fraction_input =
false;
364 _fraction_input = tmp_bool;
366 tmp_str = TQString(_num->ascii());
370 bool tmp_bool = _fraction_input;
371 _fraction_input =
false;
373 _fraction_input = tmp_bool;
375 if(_splitoffinteger_output) {
378 if (int_part == Zero)
379 tmp_str = TQString(_num->ascii());
380 else if (int_part < Zero)
381 tmp_str = int_part.
toTQString() +
" " + (int_part - *
this)._num->ascii();
383 tmp_str = int_part.
toTQString() +
" " + (*
this - int_part)._num->ascii();
385 tmp_str = TQString(_num->ascii());
387 if (width > 0 && tmp_str.length() > width) {
389 bool tmp_bool = _fraction_input;
390 _fraction_input =
false;
392 _fraction_input = tmp_bool;
399 tmp_str = TQString(_num->ascii(width));
402 tmp_str = TQString(_num->ascii(3*mpf_get_default_prec()/10));
405 return TQString(_num->ascii());
409 return roundNumber(tmp_str, prec);
416 _float_output = flag;
421 _fraction_input = flag;
426 _splitoffinteger_output = flag;
432 unsigned long int bin_prec =
static_cast<unsigned long int> 433 (double(prec) * M_LN10 / M_LN2 + 1);
435 mpf_set_default_prec(bin_prec);
443 tmp_num._num = _num->abs();
453 tmp_num._num = _num->cbrt();
463 tmp_num._num = _num->sqrt();
472 tmp_num._num = _num->intPart();
494 else if (exp < Zero) {
498 tmp_num._num = _num->power(*(tmp_num2._num));
505 tmp_num._num = _num->power(*(exp._num));
512 KNumber const KNumber::operator-(
void)
const 517 tmp_num._num = _num->change_sign();
527 tmp_num._num = _num->add(*arg2._num);
529 tmp_num.simplifyRational();
536 return *
this + (-arg2);
544 tmp_num._num = _num->multiply(*arg2._num);
546 tmp_num.simplifyRational();
556 tmp_num._num = _num->divide(*arg2._num);
558 tmp_num.simplifyRational();
566 if (
type() != IntegerType || arg2.
type() != IntegerType)
572 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
573 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
575 tmp_num._num = tmp_arg1->mod(*tmp_arg2);
582 if (
type() != IntegerType || arg2.
type() != IntegerType)
588 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
589 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
591 tmp_num._num = tmp_arg1->intAnd(*tmp_arg2);
599 if (
type() != IntegerType || arg2.
type() != IntegerType)
605 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
606 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
608 tmp_num._num = tmp_arg1->intOr(*tmp_arg2);
616 if (
type() != IntegerType || arg2.
type() != IntegerType)
619 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
620 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(arg2._num);
624 tmp_num._num = tmp_arg1->shift(*tmp_arg2);
631 if (
type() != IntegerType || arg2.
type() != IntegerType)
636 _knuminteger
const *tmp_arg1 =
dynamic_cast<_knuminteger
const *
>(_num);
637 _knuminteger
const *tmp_arg2 =
dynamic_cast<_knuminteger
const *
>(tmp_num._num);
640 delete tmp_num2._num;
641 tmp_num2._num = tmp_arg1->shift(*tmp_arg2);
648 KNumber::operator bool(
void)
const 655 KNumber::operator
signed long int(
void)
const 657 return static_cast<signed long int>(*_num);
660 KNumber::operator
unsigned long int(
void)
const 662 return static_cast<unsigned long int>(*_num);
665 KNumber::operator
unsigned long long int(
void)
const 667 #if SIZEOF_UNSIGNED_LONG == 8 668 return static_cast<unsigned long int>(*this);
669 #elif SIZEOF_UNSIGNED_LONG == 4 671 unsigned long long int tmp_num2 =
static_cast<unsigned long int>(tmp_num1) +
672 (static_cast<unsigned long long int>(
673 static_cast<unsigned long int>(tmp_num1 >>
KNumber(
"32"))) << 32) ;
675 #warning the cast operator from KNumber to unsigned long long int is probably buggy, when a sign is involved 679 return static_cast<unsigned long long int> (-
static_cast<signed long long int>(tmp_num2));
681 #error "SIZEOF_UNSIGNED_LONG is a unhandled case" 685 KNumber::operator double(
void)
const 687 return static_cast<double>(*_num);
690 int const KNumber::compare(
KNumber const & arg2)
const 692 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.