File indexing completed on 2024-05-12 17:22:39
0001 // HMath: C++ high precision math routines 0002 // Copyright (C) 2004 Ariya Hidayat <ariya.hidayat@gmail.com> 0003 // Copyright (C) 2007-2008, 2014 @heldercorreia 0004 // Copyright (C) 2008, 2009 Wolf Lammen 0005 // 0006 // This program is free software; you can redistribute it and/or 0007 // modify it under the terms of the GNU General Public License 0008 // as published by the Free Software Foundation; either version 2 0009 // of the License, or (at your option) any later version. 0010 // 0011 // This program is distributed in the hope that it will be useful, 0012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 // GNU General Public License for more details. 0015 // 0016 // You should have received a copy of the GNU General Public License 0017 // along with this program; see the file COPYING. If not, write to 0018 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 // Boston, MA 02110-1301, USA. 0020 0021 #include "hmath.h" 0022 0023 #include "floatcommon.h" 0024 #include "floatconst.h" 0025 #include "floatconvert.h" 0026 #include "floathmath.h" 0027 #include "rational.h" 0028 0029 #include <QMap> 0030 #include <QString> 0031 #include <QStringList> 0032 0033 #include <cstdio> 0034 #include <cstdlib> 0035 #include <cstring> 0036 #include <sstream> 0037 0038 #define RATIONAL_TOL HNumber("1e-20") 0039 0040 //TODO make this configurable 0041 #define HMATH_WORKING_PREC (DECPRECISION + 3) 0042 #define HMATH_EVAL_PREC (HMATH_WORKING_PREC + 2) 0043 0044 //TODO should go into a separate format file 0045 // default scale for fall back in formatting 0046 #define HMATH_MAX_SHOWN 20 0047 #define HMATH_BIN_MAX_SHOWN ((33219*HMATH_MAX_SHOWN)/10000 + 1) 0048 #define HMATH_OCT_MAX_SHOWN ((11073*HMATH_MAX_SHOWN)/10000 + 1) 0049 #define HMATH_HEX_MAX_SHOWN ((8305*HMATH_MAX_SHOWN)/10000 + 1) 0050 0051 /*------------------------ Helper routines -------------------------*/ 0052 0053 static void checkfullcancellation(cfloatnum op1, cfloatnum op2, 0054 floatnum r) 0055 { 0056 if (float_getlength(op1) != 0 0057 && float_getlength(op2) != 0 0058 && float_getlength(r) != 0) { 0059 // NaN or zero not involved in computation. 0060 int expr = float_getexponent(r); 0061 if (float_getexponent(op1) - expr >= HMATH_WORKING_PREC - 1 0062 || float_getexponent(op2) - expr >= HMATH_WORKING_PREC - 1) 0063 float_setzero(r); 0064 } 0065 } 0066 0067 static char checkAdd(floatnum dest, cfloatnum s1, cfloatnum s2, int digits) 0068 { 0069 if (float_add(dest, s1, s2, digits) 0070 && float_getsign(s1) + float_getsign(s2) == 0) 0071 checkfullcancellation(s1, s2, dest); 0072 return float_isnan(dest); 0073 } 0074 0075 static char checkSub(floatnum dest, cfloatnum s1, cfloatnum s2, int digits) 0076 { 0077 if (float_sub(dest, s1, s2, digits) 0078 && float_getsign(s1) - float_getsign(s2) == 0) 0079 checkfullcancellation(s1, s2, dest); 0080 return float_isnan(dest); 0081 } 0082 0083 static void h_init() 0084 { 0085 static bool h_initialized = false; 0086 if (!h_initialized) { 0087 h_initialized = true; 0088 //TODO related to formats, get rid of it. 0089 float_stdconvert(); 0090 } 0091 } 0092 0093 static void checkpoleorzero(floatnum result, floatnum x) 0094 { 0095 if (float_getlength(result) == 0 || float_getlength(x) == 0) 0096 return; 0097 int expx = float_getexponent(x)-HMATH_WORKING_PREC+1; 0098 int expr = float_getexponent(result); 0099 if (expr <= expx) 0100 float_setzero(result); 0101 else if (expr >= -expx) { 0102 float_setnan(result); 0103 float_seterror(EvalUnstable); 0104 } 0105 } 0106 0107 static char roundResult(floatnum x) 0108 { 0109 if (float_isnan(x)) // Avoids setting float_error. 0110 return 0; 0111 return float_round(x, x, HMATH_WORKING_PREC, TONEAREST); 0112 } 0113 0114 /*--------------------------- HNumberPrivate --------------------*/ 0115 0116 class HNumberPrivate 0117 { 0118 public: 0119 HNumberPrivate(); 0120 ~HNumberPrivate(); 0121 //TODO make this a variant 0122 floatstruct fnum; 0123 Error error; 0124 }; 0125 0126 HNumberPrivate::HNumberPrivate() 0127 : error(Success) 0128 { 0129 h_init(); 0130 float_create(&fnum); 0131 } 0132 0133 HNumberPrivate::~HNumberPrivate() 0134 { 0135 float_free(&fnum); 0136 } 0137 0138 typedef char (*Float1ArgND)(floatnum x); 0139 typedef char (*Float1Arg)(floatnum x, int digits); 0140 typedef char (*Float2ArgsND)(floatnum result, cfloatnum p1, cfloatnum p2); 0141 typedef char (*Float2Args)(floatnum result, cfloatnum p1, cfloatnum p2, int digits); 0142 0143 static Error checkNaNParam(const HNumberPrivate& v1, 0144 const HNumberPrivate* v2 = 0) 0145 { 0146 if (!float_isnan(&v1.fnum) && (!v2 || !float_isnan(&v2->fnum))) 0147 return Success; 0148 Error error = v1.error; 0149 if (error == Success && v2) 0150 error = v2->error; 0151 return error == 0? NoOperand : error; 0152 } 0153 0154 void roundSetError(HNumberPrivate* dest) 0155 { 0156 dest->error = float_geterror(); 0157 floatnum dfnum = &dest->fnum; 0158 if (dest->error != Success) 0159 float_setnan(dfnum); 0160 if (!float_isnan(dfnum)) 0161 float_round(dfnum, dfnum, HMATH_WORKING_PREC, TONEAREST); 0162 } 0163 0164 void call2Args(HNumberPrivate* dest, HNumberPrivate* n1, HNumberPrivate* n2, Float2Args func) 0165 { 0166 dest->error = checkNaNParam(*n1, n2); 0167 if (dest->error == Success) { 0168 floatnum dfnum = &dest->fnum; 0169 func(dfnum, &n1->fnum, &n2->fnum, HMATH_EVAL_PREC); 0170 roundSetError(dest); 0171 } 0172 } 0173 0174 void call2ArgsND(HNumberPrivate* dest, HNumberPrivate* n1, HNumberPrivate* n2, Float2ArgsND func) 0175 { 0176 dest->error = checkNaNParam(*n1, n2); 0177 if (dest->error == Success) { 0178 floatnum dfnum = &dest->fnum; 0179 func(dfnum, &n1->fnum, &n2->fnum); 0180 roundSetError(dest); 0181 } 0182 } 0183 0184 void call1Arg(HNumberPrivate* dest, HNumberPrivate* n, Float1Arg func) 0185 { 0186 dest->error = checkNaNParam(*n); 0187 if (dest->error == Success) { 0188 floatnum dfnum = &dest->fnum; 0189 float_copy(dfnum, &n->fnum, HMATH_EVAL_PREC); 0190 func(dfnum, HMATH_EVAL_PREC); 0191 roundSetError(dest); 0192 } 0193 } 0194 0195 void call1ArgPoleCheck(HNumberPrivate* dest, HNumberPrivate* n, Float1Arg func) 0196 { 0197 dest->error = checkNaNParam(*n); 0198 if (dest->error == Success) { 0199 floatnum dfnum = &dest->fnum; 0200 float_copy(dfnum, &n->fnum, HMATH_EVAL_PREC); 0201 if (func(dfnum, HMATH_EVAL_PREC)) 0202 checkpoleorzero(dfnum, &n->fnum); 0203 roundSetError(dest); 0204 } 0205 } 0206 0207 void call1ArgND(HNumberPrivate* dest, HNumberPrivate* n, Float1ArgND func) 0208 { 0209 dest->error = checkNaNParam(*n); 0210 if (dest->error == Success) 0211 { 0212 floatnum dfnum = &dest->fnum; 0213 float_copy(dfnum, &n->fnum, HMATH_EVAL_PREC); 0214 func(dfnum); 0215 roundSetError(dest); 0216 } 0217 } 0218 0219 static char modwrap(floatnum result, cfloatnum p1, cfloatnum p2, int /*digits*/) 0220 { 0221 floatstruct tmp; 0222 float_create(&tmp); 0223 char ok = float_divmod(&tmp, result, p1, p2, INTQUOT); 0224 float_free(&tmp); 0225 return ok; 0226 } 0227 0228 char idivwrap(floatnum result, cfloatnum p1, cfloatnum p2) 0229 { 0230 floatstruct tmp; 0231 int save = float_setprecision(DECPRECISION); 0232 float_create(&tmp); 0233 char ok = float_divmod(result, &tmp, p1, p2, INTQUOT); 0234 float_free(&tmp); 0235 float_setprecision(save); 0236 return ok; 0237 } 0238 0239 /*-------------------------- HNumber -------------------*/ 0240 0241 /** 0242 * Creates a new number. 0243 */ 0244 HNumber::HNumber() : d(new HNumberPrivate) 0245 { 0246 } 0247 0248 /** 0249 * Copies from another number. 0250 */ 0251 HNumber::HNumber(const HNumber& hn) : d(new HNumberPrivate) 0252 { 0253 operator=(hn); 0254 } 0255 0256 /** 0257 * Creates a new number from an integer value. 0258 */ 0259 HNumber::HNumber(int i) : d(new HNumberPrivate) 0260 { 0261 float_setinteger(&d->fnum, i); 0262 } 0263 0264 /** 0265 * Creates a new number from a string. 0266 */ 0267 HNumber::HNumber(const char* str) : d(new HNumberPrivate) 0268 { 0269 t_itokens tokens; 0270 0271 if ((d->error = parse(&tokens, &str)) == Success && *str == 0) 0272 d->error = float_in(&d->fnum, &tokens); 0273 float_geterror(); 0274 } 0275 0276 HNumber::HNumber(const QJsonObject& json) 0277 : d(new HNumberPrivate) 0278 { 0279 *this = deSerialize(json); 0280 } 0281 0282 /** 0283 * Destroys this number. 0284 */ 0285 HNumber::~HNumber() 0286 { 0287 delete d; 0288 } 0289 0290 /** 0291 * Returns the error code kept with a NaN. 0292 */ 0293 Error HNumber::error() const 0294 { 0295 return d->error; 0296 } 0297 0298 /** 0299 * Returns true if this number is Not a Number (NaN). 0300 */ 0301 bool HNumber::isNan() const 0302 { 0303 return float_isnan(&d->fnum) != 0; 0304 } 0305 0306 /** 0307 * Returns true if this number is zero. 0308 */ 0309 bool HNumber::isZero() const 0310 { 0311 return float_iszero(&d->fnum) != 0; 0312 } 0313 0314 /** 0315 * Returns true if this number is more than zero. 0316 */ 0317 bool HNumber::isPositive() const 0318 { 0319 return float_getsign(&d->fnum) > 0; 0320 } 0321 0322 /** 0323 * Returns true if this number is less than zero. 0324 */ 0325 bool HNumber::isNegative() const 0326 { 0327 return float_getsign(&d->fnum) < 0; 0328 } 0329 0330 /** 0331 * Returns true if this number is integer. 0332 */ 0333 bool HNumber::isInteger() const 0334 { 0335 return float_isinteger(&d->fnum) != 0; 0336 } 0337 0338 void HNumber::serialize(QJsonObject& json) const 0339 { 0340 json["value"] = HMath::format(*this, Format::Fixed() + Format::Precision(DECPRECISION)); 0341 } 0342 0343 HNumber HNumber::deSerialize(const QJsonObject& json) 0344 { 0345 HNumber result; 0346 if (json.contains("value")) { 0347 QString str = json["value"].toString(); 0348 str.replace(",", "."); 0349 result = HNumber(str.toLatin1().constData()); 0350 } 0351 return result; 0352 } 0353 0354 /** 0355 * Returns the number as an int. 0356 * It is meant to convert small (integer) numbers only and no 0357 * checking is done whatsoever. 0358 */ 0359 int HNumber::toInt() const 0360 { 0361 return float_asinteger(&d->fnum); 0362 } 0363 0364 /** 0365 * Assigns from another number. 0366 */ 0367 HNumber& HNumber::operator=(const HNumber& hn) 0368 { 0369 d->error = hn.error(); 0370 0371 float_copy(&d->fnum, &hn.d->fnum, EXACT); 0372 0373 return *this; 0374 } 0375 0376 0377 /** 0378 * Adds another number. 0379 */ 0380 HNumber HNumber::operator+(const HNumber& num) const 0381 { 0382 if (this->isZero()) 0383 return num; 0384 if (num.isZero()) 0385 return *this; 0386 HNumber result; 0387 call2Args(result.d, d, num.d, checkAdd); 0388 return result; 0389 } 0390 0391 /** 0392 * Adds another number. 0393 */ 0394 HNumber& HNumber::operator+=(const HNumber& num) 0395 { 0396 return operator=(*this + num); 0397 } 0398 0399 /** 0400 * Subtract from another number. 0401 */ 0402 HNumber operator-(const HNumber& n1, const HNumber& n2) 0403 { 0404 HNumber result; 0405 call2Args(result.d, n1.d, n2.d, checkSub); 0406 return result; 0407 } 0408 0409 /** 0410 * Subtract from another number. 0411 */ 0412 HNumber& HNumber::operator-=(const HNumber& num) 0413 { 0414 return operator=(*this - num); 0415 } 0416 0417 /** 0418 * Multiplies with another number. 0419 */ 0420 HNumber HNumber::operator*(const HNumber& num) const 0421 { 0422 HNumber result; 0423 call2Args(result.d, d, num.d, float_mul); 0424 return result; 0425 } 0426 0427 /** 0428 * Multiplies with another number. 0429 */ 0430 HNumber& HNumber::operator*=(const HNumber& num) 0431 { 0432 return operator=(*this * num); 0433 } 0434 0435 /** 0436 * Divides with another number. 0437 */ 0438 HNumber HNumber::operator/(const HNumber& num) const 0439 { 0440 HNumber result; 0441 call2Args(result.d, d, num.d, float_div); 0442 return result; 0443 } 0444 0445 /** 0446 * Divides with another number. 0447 */ 0448 HNumber& HNumber::operator/=(const HNumber& num) 0449 { 0450 return operator=(*this / num); 0451 } 0452 0453 /** 0454 * Modulo (rest of integer division) 0455 */ 0456 HNumber HNumber::operator%(const HNumber& num) const 0457 { 0458 HNumber result; 0459 call2Args(result.d, d, num.d, modwrap); 0460 return result; 0461 } 0462 0463 /** 0464 * Returns -1, 0, 1 if *this is less than, equal to, or more than other. 0465 */ 0466 int HNumber::compare(const HNumber& other) const 0467 { 0468 int result = float_relcmp(&d->fnum, &other.d->fnum, HMATH_EVAL_PREC-1); 0469 float_geterror(); // clears error, if one operand was a NaN 0470 return result; 0471 } 0472 0473 /** 0474 * Returns true if l is greater than r. 0475 */ 0476 bool operator>(const HNumber& l, const HNumber& r) 0477 { 0478 return l.compare(r) > 0; 0479 } 0480 0481 /** 0482 * Returns true if l is less than r. 0483 */ 0484 bool operator<(const HNumber& l, const HNumber& r) 0485 { 0486 return l.compare(r) < 0; 0487 } 0488 0489 /** 0490 * Returns true if l is greater than or equal to r. 0491 */ 0492 bool operator>=(const HNumber& l, const HNumber& r) 0493 { 0494 return l.compare(r) >= 0; 0495 } 0496 0497 /** 0498 * Returns true if l is less than or equal to r. 0499 */ 0500 bool operator<=(const HNumber& l, const HNumber& r) 0501 { 0502 return l.compare(r) <= 0; 0503 } 0504 0505 /** 0506 * Returns true if l is equal to r. 0507 */ 0508 bool operator==(const HNumber& l, const HNumber& r) 0509 { 0510 return l.compare(r) == 0; 0511 } 0512 0513 /** 0514 * Returns true if l is not equal to r. 0515 */ 0516 bool operator!=(const HNumber& l, const HNumber& r) 0517 { 0518 return l.compare(r) != 0; 0519 } 0520 0521 /** 0522 * Bitwise ANDs the integral parts of both operands. 0523 * Yields NaN, if any operand exeeds the logic range 0524 */ 0525 HNumber HNumber::operator&(const HNumber& num) const 0526 { 0527 HNumber result; 0528 call2ArgsND(result.d, d, num.d, float_and); 0529 return result; 0530 } 0531 0532 /** 0533 * Bitwise ANDs the integral parts of both operands. 0534 * Yields NaN, if any operand exeeds the logic range 0535 */ 0536 HNumber& HNumber::operator&=(const HNumber& num) 0537 { 0538 return operator=(*this & num); 0539 } 0540 0541 /** 0542 * Bitwise ORs the integral parts of both operands. 0543 * Yields NaN, if any operand exeeds the logic range 0544 */ 0545 HNumber HNumber::operator|(const HNumber& num) const 0546 { 0547 HNumber result; 0548 call2ArgsND(result.d, d, num.d, float_or); 0549 return result; 0550 } 0551 0552 /** 0553 * Bitwise ORs the integral parts of both operands. 0554 * Yields NaN, if any operand exeeds the logic range 0555 */ 0556 HNumber& HNumber::operator|=(const HNumber& num) 0557 { 0558 return operator=(*this | num); 0559 } 0560 0561 /** 0562 * Bitwise XORs the integral parts of both operands. 0563 * Yields NaN, if any operand exeeds the logic range 0564 */ 0565 HNumber HNumber::operator^(const HNumber& num) const 0566 { 0567 HNumber result; 0568 call2ArgsND(result.d, d, num.d, float_xor); 0569 return result; 0570 } 0571 0572 /** 0573 * Bitwise XORs the integral parts of both operands. 0574 * Yields NaN, if any operand exeeds the logic range 0575 */ 0576 HNumber& HNumber::operator^=(const HNumber& num) 0577 { 0578 return operator=(*this ^ num); 0579 } 0580 0581 /** 0582 * Bitwise NOTs the integral part *this. 0583 * Yields NaN, if *this exeeds the logic range 0584 */ 0585 HNumber HNumber::operator~() const 0586 { 0587 HNumber result; 0588 call1ArgND(result.d, d, float_not); 0589 return result; 0590 } 0591 0592 /** 0593 * Changes the sign. 0594 */ 0595 HNumber operator-(const HNumber& x) 0596 { 0597 HNumber result; 0598 call1ArgND(result.d, x.d, float_neg); 0599 return result; 0600 } 0601 0602 /** 0603 * Shifts the integral part of <*this> to the left by 0604 * the parameters value's bits. Zeros are shifted in 0605 * to the right, shifted out bits are dropped. 0606 * Yields NaN, if the operand exeeds the logic range, 0607 * or the shift count is not a non-negative integer. 0608 */ 0609 HNumber HNumber::operator<<(const HNumber& num) const 0610 { 0611 HNumber result; 0612 call2ArgsND(result.d, d, num.d, float_shl); 0613 return result; 0614 } 0615 0616 /** 0617 * Shifts the integral part of <*this> to the right by 0618 * the parameters value's bits. The most significand 0619 * bit is duplicated to the left, shifted out bits are dropped 0620 * (signed or arithmethic shift right). 0621 * Yields NaN, if the operand exeeds the logic range, 0622 * or the shift count is not a non-negative integer. 0623 */ 0624 HNumber HNumber::operator>>(const HNumber& num) const 0625 { 0626 HNumber result; 0627 call2ArgsND(result.d, d, num.d, float_shr); 0628 return result; 0629 } 0630 0631 HNumber::Format::Format() 0632 : base(Base::Null) 0633 , radixChar(RadixChar::Null) 0634 , mode(Mode::Null) 0635 , precision(PrecisionNull) 0636 { 0637 } 0638 0639 HNumber::Format::Format(const HNumber::Format& other) 0640 : base(other.base) 0641 , radixChar(other.radixChar) 0642 , mode(other.mode) 0643 , precision(other.precision) 0644 { 0645 } 0646 0647 HNumber::Format HNumber::Format::operator+(const HNumber::Format& other) const 0648 { 0649 Format result; 0650 result.base = (this->base != Base::Null) ? this->base : other.base; 0651 result.radixChar = (this->radixChar != RadixChar::Null) ? this->radixChar : other.radixChar; 0652 result.mode = (this->mode != Mode::Null) ? this->mode : other.mode; 0653 result.precision = (this->precision != PrecisionNull) ? this->precision : other.precision; 0654 return result; 0655 } 0656 0657 HNumber::Format HNumber::Format::Binary() 0658 { 0659 Format result; 0660 result.base = Base::Binary; 0661 return result; 0662 } 0663 0664 HNumber::Format HNumber::Format::Octal() 0665 { 0666 Format result; 0667 result.base = Base::Octal; 0668 return result; 0669 } 0670 0671 HNumber::Format HNumber::Format::Decimal() 0672 { 0673 Format result; 0674 result.base = Base::Decimal; 0675 return result; 0676 } 0677 0678 HNumber::Format HNumber::Format::Hexadecimal() 0679 { 0680 Format result; 0681 result.base = Base::Hexadecimal; 0682 return result; 0683 } 0684 0685 HNumber::Format HNumber::Format::Precision(int prec) 0686 { 0687 Format result; 0688 result.precision = prec; 0689 return result; 0690 } 0691 0692 HNumber::Format HNumber::Format::Point() 0693 { 0694 Format result; 0695 result.radixChar = RadixChar::Point; 0696 return result; 0697 } 0698 0699 HNumber::Format HNumber::Format::Comma() 0700 { 0701 Format result; 0702 result.radixChar = RadixChar::Comma; 0703 return result; 0704 } 0705 0706 HNumber::Format HNumber::Format::General() 0707 { 0708 Format result; 0709 result.mode = Mode::General; 0710 return result; 0711 } 0712 0713 HNumber::Format HNumber::Format::Fixed() 0714 { 0715 Format result; 0716 result.mode = Mode::Fixed; 0717 return result; 0718 } 0719 0720 HNumber::Format HNumber::Format::Scientific() 0721 { 0722 Format result; 0723 result.mode = Mode::Scientific; 0724 return result; 0725 } 0726 0727 HNumber::Format HNumber::Format::Engineering() 0728 { 0729 Format result; 0730 result.mode = Mode::Engineering; 0731 return result; 0732 } 0733 0734 namespace { 0735 0736 char* _doFormat(cfloatnum x, signed char base, signed char expbase, char outmode, int prec, unsigned flags) 0737 { 0738 t_otokens tokens; 0739 char intbuf[BINPRECISION+1]; 0740 char fracbuf[BINPRECISION+1]; 0741 int sz = 0; 0742 char* str = nullptr; 0743 switch (base) { 0744 case 2: 0745 sz = BINPRECISION+1; 0746 break; 0747 case 8: 0748 sz = OCTPRECISION+1; 0749 break; 0750 case 10: 0751 sz = DECPRECISION+1; 0752 break; 0753 case 16: 0754 sz = HEXPRECISION+1; 0755 break; 0756 } 0757 tokens.intpart.sz = sz; 0758 tokens.intpart.buf = intbuf; 0759 tokens.fracpart.sz = sz; 0760 tokens.fracpart.buf = fracbuf; 0761 0762 floatstruct tmp; 0763 float_create(&tmp); 0764 float_copy(&tmp, x, DECPRECISION + 2); 0765 if (float_out(&tokens, &tmp, prec, base, outmode) == Success) 0766 { 0767 sz = cattokens(nullptr, -1, &tokens, expbase, flags); 0768 str = (char*)malloc(sz); 0769 cattokens(str, sz, &tokens, expbase, flags); 0770 } 0771 float_free(&tmp); 0772 return str; 0773 } 0774 0775 /** 0776 * Formats the given number as string, using specified decimal digits. 0777 * Note that the returned string must be freed. 0778 */ 0779 char* formatFixed(cfloatnum x, int prec, int base = 10) 0780 { 0781 unsigned flags = IO_FLAG_SUPPRESS_PLUS + IO_FLAG_SUPPRESS_DOT + IO_FLAG_SUPPRESS_EXPZERO; 0782 if (base != 10) 0783 flags += IO_FLAG_SHOW_BASE + IO_FLAG_SHOW_EXPBASE; 0784 if (prec < 0) { 0785 prec = HMATH_MAX_SHOWN; 0786 } 0787 flags |= IO_FLAG_SUPPRESS_TRL_ZERO; 0788 char* result = _doFormat(x, base, base, IO_MODE_FIXPOINT, prec, flags); 0789 return result ? result : _doFormat(x, base, base, IO_MODE_SCIENTIFIC, HMATH_MAX_SHOWN, flags); 0790 } 0791 0792 /** 0793 * Formats the given number as string, in scientific format. 0794 * Note that the returned string must be freed. 0795 */ 0796 char* formatScientific(cfloatnum x, int prec, int base = 10) 0797 { 0798 unsigned flags = IO_FLAG_SUPPRESS_PLUS + IO_FLAG_SUPPRESS_DOT + IO_FLAG_SUPPRESS_EXPPLUS; 0799 if (base != 10) 0800 flags += IO_FLAG_SHOW_BASE + IO_FLAG_SHOW_EXPBASE; 0801 if (prec < 0) { 0802 flags |= IO_FLAG_SUPPRESS_TRL_ZERO; 0803 prec = HMATH_MAX_SHOWN; 0804 } 0805 return _doFormat(x, base, base, IO_MODE_SCIENTIFIC, prec, flags); 0806 } 0807 0808 /** 0809 * Formats the given number as string, in engineering notation. 0810 * Note that the returned string must be freed. 0811 */ 0812 char* formatEngineering(cfloatnum x, int prec, int base = 10) 0813 { 0814 unsigned flags = IO_FLAG_SUPPRESS_PLUS + IO_FLAG_SUPPRESS_EXPPLUS; 0815 if (base != 10) 0816 flags += IO_FLAG_SHOW_BASE + IO_FLAG_SHOW_EXPBASE; 0817 if (prec <= 1) { 0818 flags |= IO_FLAG_SUPPRESS_TRL_ZERO + IO_FLAG_SUPPRESS_DOT; 0819 prec = HMATH_MAX_SHOWN; 0820 } 0821 return _doFormat(x, base, base, IO_MODE_ENG, prec, flags); 0822 } 0823 0824 /** 0825 * Formats the given number as string, using specified decimal digits. 0826 * Note that the returned string must be freed. 0827 */ 0828 char* formatGeneral(cfloatnum x, int prec, int base = 10) 0829 { 0830 // find the exponent and the factor 0831 int expd = float_getexponent(x); 0832 0833 char* str; 0834 if (expd > 5) 0835 str = formatScientific(x, prec, base); 0836 else if (expd < -4) 0837 str = formatScientific(x, prec, base); 0838 else if ((expd < 0) && (prec >= 0) && (expd < -prec)) 0839 str = formatScientific(x, prec, base); 0840 else 0841 str = formatFixed(x, prec, base); 0842 0843 return str; 0844 } 0845 0846 0847 } /* unnamed namespace */ 0848 0849 /** 0850 * Formats the given number as string, using specified decimal digits. 0851 */ 0852 QString HMath::format(const HNumber& hn, HNumber::Format format) 0853 { 0854 char* rs = 0; 0855 0856 if (format.precision < 0) // This includes PrecisionNull 0857 format.precision = -1; 0858 0859 int base; 0860 switch (format.base) { 0861 case HNumber::Format::Base::Binary: 0862 base = 2; 0863 break; 0864 case HNumber::Format::Base::Octal: 0865 base = 8; 0866 break; 0867 case HNumber::Format::Base::Hexadecimal: 0868 base = 16; 0869 break; 0870 case HNumber::Format::Base::Decimal: 0871 case HNumber::Format::Base::Null: 0872 default: 0873 base = 10; 0874 break; 0875 } 0876 0877 switch (format.mode) { 0878 case HNumber::Format::Mode::Fixed: 0879 rs = formatFixed(&hn.d->fnum, format.precision, base); 0880 break; 0881 case HNumber::Format::Mode::Scientific: 0882 rs = formatScientific(&hn.d->fnum, format.precision, base) ; 0883 break; 0884 case HNumber::Format::Mode::Engineering: 0885 rs = formatEngineering(&hn.d->fnum, format.precision, base); 0886 break; 0887 case HNumber::Format::Mode::General: 0888 default: 0889 rs = formatGeneral(&hn.d->fnum, format.precision, base); 0890 } 0891 0892 QString result(rs); 0893 free(rs); 0894 return result; 0895 } 0896 0897 /** 0898 * Converts radians to degrees. 0899 */ 0900 HNumber HMath::rad2deg(const HNumber& angle) 0901 { 0902 return angle * (HNumber(180) / HMath::pi()); 0903 } 0904 0905 /** 0906 * Converts degrees to radians. 0907 */ 0908 HNumber HMath::deg2rad(const HNumber& angle) 0909 { 0910 return angle * (HMath::pi() / HNumber(180)); 0911 } 0912 0913 /** 0914 * Converts radians to gons. 0915 */ 0916 HNumber HMath::rad2gon(const HNumber& angle) 0917 { 0918 return angle * (HNumber(200) / HMath::pi()); 0919 } 0920 0921 /** 0922 * Converts gons to radians. 0923 */ 0924 HNumber HMath::gon2rad(const HNumber& angle) 0925 { 0926 return angle * (HMath::pi() / HNumber(200)); 0927 } 0928 0929 /** 0930 * Returns the constant e (Euler's number). 0931 */ 0932 HNumber HMath::e() 0933 { 0934 HNumber value; 0935 float_copy(&value.d->fnum, &cExp, HMATH_EVAL_PREC); 0936 return value; 0937 } 0938 0939 /** 0940 * Returns the constant Pi. 0941 */ 0942 HNumber HMath::pi() 0943 { 0944 HNumber value; 0945 float_copy(&value.d->fnum, &cPi, HMATH_EVAL_PREC); 0946 return value; 0947 } 0948 0949 /** 0950 * Returns the constant Phi (golden number). 0951 */ 0952 HNumber HMath::phi() 0953 { 0954 HNumber value; 0955 float_copy(&value.d->fnum, &cPhi, HMATH_EVAL_PREC); 0956 return value; 0957 } 0958 0959 /** 0960 * Returns a NaN (Not a Number) with error set to 0961 * passed parameter. 0962 */ 0963 HNumber HMath::nan(Error error) 0964 { 0965 HNumber result; 0966 result.d->error = error; 0967 return result; 0968 } 0969 0970 /** 0971 * Returns the maximum of two numbers. 0972 */ 0973 HNumber HMath::max(const HNumber& n1, const HNumber& n2) 0974 { 0975 switch (float_cmp(&n1.d->fnum, &n2.d->fnum)) 0976 { 0977 case 0: 0978 case 1: return n1; 0979 case -1: return n2; 0980 default: return HMath::nan(checkNaNParam(*n1.d, n2.d)); 0981 } 0982 } 0983 0984 /** 0985 * Returns the minimum of two numbers. 0986 */ 0987 HNumber HMath::min(const HNumber& n1, const HNumber& n2) 0988 { 0989 switch (float_cmp(&n1.d->fnum, &n2.d->fnum)) 0990 { 0991 case 0: 0992 case 1: return n2; 0993 case -1: return n1; 0994 default: return HMath::nan(checkNaNParam(*n1.d, n2.d)); 0995 } 0996 } 0997 0998 /** 0999 * Returns the absolute value of n. 1000 */ 1001 HNumber HMath::abs(const HNumber& n) 1002 { 1003 HNumber result; 1004 call1ArgND(result.d, n.d, float_abs); 1005 return result; 1006 } 1007 1008 /** 1009 * Rounds n to the specified decimal digits. 1010 */ 1011 HNumber HMath::round(const HNumber& n, int prec) 1012 { 1013 if (n.isNan()) 1014 return HMath::nan(checkNaNParam(*n.d)); 1015 HNumber result(n); 1016 floatnum rnum = &result.d->fnum; 1017 int exp = float_getexponent(rnum); 1018 1019 // Avoid exponent overflow later. 1020 if (prec > HMATH_WORKING_PREC && exp > 0) 1021 prec = HMATH_WORKING_PREC; 1022 if (prec < 0 && -exp-1 > prec) 1023 float_setzero(rnum); 1024 else if (exp + prec < HMATH_WORKING_PREC) { 1025 float_addexp(rnum, prec); 1026 float_roundtoint(rnum, TONEAREST); 1027 float_addexp(rnum, -prec); 1028 } 1029 return result; 1030 } 1031 1032 /** 1033 * Truncates n to the specified decimal digits. 1034 */ 1035 HNumber HMath::trunc(const HNumber& n, int prec) 1036 { 1037 if (n.isNan()) 1038 return HMath::nan(checkNaNParam(*n.d)); 1039 HNumber result(n); 1040 floatnum rnum = &result.d->fnum; 1041 int exp = float_getexponent(rnum); 1042 // Avoid exponent overflow later on. 1043 if (prec > HMATH_WORKING_PREC && exp > 0) 1044 prec = HMATH_WORKING_PREC; 1045 if (prec < 0 && -exp-1 > prec) 1046 float_setzero(rnum); 1047 else if (exp + prec < HMATH_WORKING_PREC) { 1048 float_addexp(rnum, prec); 1049 float_roundtoint(rnum, TOZERO); 1050 float_addexp(rnum, -prec); 1051 } 1052 return result; 1053 } 1054 1055 /** 1056 * Returns the integer part of n. 1057 */ 1058 HNumber HMath::integer(const HNumber& n) 1059 { 1060 HNumber result; 1061 call1ArgND(result.d, n.d, float_int); 1062 return result; 1063 } 1064 1065 /** 1066 * Returns the fraction part of n. 1067 */ 1068 HNumber HMath::frac(const HNumber& n) 1069 { 1070 HNumber result; 1071 call1ArgND(result.d, n.d, float_frac); 1072 return result; 1073 } 1074 1075 #define CHECK_NAN \ 1076 if (n.isNan()) \ 1077 return HMath::nan(checkNaNParam(*n.d)); 1078 1079 #define RETURN_IF_NEAR_INT \ 1080 HNumber nearest_int(n); \ 1081 float_roundtoint(&nearest_int.d->fnum, TONEAREST); \ 1082 /* Note: float_relcmp doesn't work here, because it's doesn't check the relative */ \ 1083 /* tolerance if exponents are not the same. */ \ 1084 /* FIXME: Put this value as parameter. */ \ 1085 /* Kudos to the guy who can figure out why we need such a small tolerance here. */ \ 1086 /* 1e-70 does not work, but 1e-10000 does. */ \ 1087 if (HMath::abs(n - nearest_int) < HNumber("1e-100") * HMath::abs(n + nearest_int)) /* FIXME: Make configurable. */ \ 1088 return nearest_int; \ 1089 1090 /** 1091 * Returns the floor of n. 1092 */ 1093 HNumber HMath::floor(const HNumber& n) 1094 { 1095 CHECK_NAN; 1096 RETURN_IF_NEAR_INT; 1097 // Actual rounding, if needed. 1098 HNumber r(n); 1099 float_roundtoint(&r.d->fnum, TOMINUSINFINITY); 1100 return r; 1101 } 1102 1103 /** 1104 * Returns the ceiling of n. 1105 */ 1106 HNumber HMath::ceil(const HNumber& n) 1107 { 1108 CHECK_NAN; 1109 RETURN_IF_NEAR_INT; 1110 // Actual rounding, if needed. 1111 HNumber r(n); 1112 float_roundtoint(&r.d->fnum, TOPLUSINFINITY); 1113 return r; 1114 } 1115 1116 /** 1117 * Returns the greatest common divisor of n1 and n2. 1118 */ 1119 HNumber HMath::gcd(const HNumber& n1, const HNumber& n2) 1120 { 1121 if (!n1.isInteger() || !n2.isInteger()) { 1122 Error error = checkNaNParam(*n1.d, n2.d); 1123 if (error != Success) 1124 return HMath::nan(error); 1125 return HMath::nan(TypeMismatch); 1126 } 1127 1128 HNumber a = abs(n1); 1129 HNumber b = abs(n2); 1130 1131 if (a == 0) 1132 return b; 1133 if (b == 0) 1134 return a; 1135 1136 // Run Euclidean algorithm. 1137 while (true) { 1138 a = a % b; 1139 1140 if (a == 0) 1141 return b; 1142 1143 b = b % a; 1144 1145 if (b == 0) 1146 return a; 1147 } 1148 } 1149 1150 /** 1151 * Performs an integer divide. 1152 */ 1153 HNumber HMath::idiv(const HNumber& dividend, const HNumber& divisor) 1154 { 1155 HNumber result; 1156 call2ArgsND(result.d, dividend.d, divisor.d, idivwrap); 1157 if (result.error() == TooExpensive) 1158 result.d->error = Overflow; 1159 return result; 1160 } 1161 1162 /** 1163 * Returns the square root of n. If n is negative, returns NaN. 1164 */ 1165 HNumber HMath::sqrt(const HNumber& n) 1166 { 1167 HNumber result; 1168 call1Arg(result.d, n.d, float_sqrt); 1169 return result; 1170 } 1171 1172 /** 1173 * Returns the cube root of n. 1174 */ 1175 HNumber HMath::cbrt(const HNumber& n) 1176 { 1177 if (n.isNan()) 1178 return HMath::nan(checkNaNParam(*n.d)); 1179 if (n.isZero()) 1180 return n; 1181 HNumber r; 1182 floatnum rnum = &r.d->fnum; 1183 1184 // iterations to approximate result 1185 // X[i+1] = (2/3)X[i] + n / (3 * X[i]^2)) 1186 // initial guess = sqrt(n) 1187 // r = X[i], q = X[i+1], a = n 1188 1189 floatstruct a, q; 1190 float_create(&a); 1191 float_create(&q); 1192 float_copy(&a, &n.d->fnum, HMATH_EVAL_PREC); 1193 signed char sign = float_getsign(&a); 1194 float_abs(&a); 1195 int expn = float_getexponent(&a); 1196 float_setexponent(&a, expn % 3); 1197 expn /= 3; 1198 1199 int digits = 0; 1200 float_copy(&q, &a, 2); 1201 float_sqrt(&q, 2); 1202 1203 while (digits < HMATH_EVAL_PREC/2 + 3) { 1204 digits = 4 * digits + 2; 1205 if (digits > HMATH_EVAL_PREC+2) 1206 digits = HMATH_EVAL_PREC+2; 1207 float_move(rnum, &q); 1208 float_mul(&q, rnum, rnum, digits); 1209 float_div(&q, &a, &q, digits); 1210 float_add(&q, &q, rnum, digits); 1211 float_add(&q, &q, rnum, digits); 1212 float_div(&q, &q, &c3, digits); 1213 float_sub(rnum, rnum, &q, 3); 1214 if (!float_iszero(rnum)) 1215 digits = float_getexponent(&q) - float_getexponent(rnum); 1216 } 1217 float_move(rnum, &q); 1218 float_free(&q); 1219 float_free(&a); 1220 float_setsign(rnum, sign); 1221 float_addexp(rnum, expn); 1222 1223 roundResult(&r.d->fnum); 1224 return r; 1225 } 1226 1227 /** 1228 * Raises n1 to an integer n. 1229 */ 1230 HNumber HMath::raise(const HNumber& n1, int n) 1231 { 1232 HNumber r; 1233 float_raisei(&r.d->fnum, &n1.d->fnum, n, HMATH_EVAL_PREC); 1234 roundSetError(r.d); 1235 return r; 1236 } 1237 1238 /** 1239 * Raises n1 to n2. 1240 */ 1241 HNumber HMath::raise(const HNumber& n1, const HNumber& n2) 1242 { 1243 HNumber result; 1244 HNumber temp = n1; 1245 Rational exp; 1246 bool change_sgn=false; 1247 if (n1.isNegative() && !n2.isInteger()){ 1248 //Try to convert n2 to a Rational. If n2 is not rational, return NaN. 1249 // For negative bases only allow odd denominators. 1250 exp = Rational(n2); 1251 if (abs(exp.toHNumber() - n2) >= RATIONAL_TOL 1252 || (n1.isNegative() && exp.denominator()%2 == 0)) 1253 return HMath::nan(OutOfDomain); 1254 if (n1.isNegative() && !n2.isInteger()) { 1255 temp = -temp; 1256 change_sgn = true; 1257 } 1258 } 1259 1260 call2Args(result.d, temp.d, n2.d, float_raise); 1261 result *= (change_sgn) ? -1 : 1; 1262 return result; 1263 } 1264 1265 /** 1266 * Returns e raised to x. 1267 */ 1268 HNumber HMath::exp(const HNumber& x) 1269 { 1270 HNumber result; 1271 call1Arg(result.d, x.d, float_exp); 1272 return result; 1273 }; 1274 1275 /** 1276 * Returns the natural logarithm of x. 1277 * If x is non positive, returns NaN. 1278 */ 1279 HNumber HMath::ln(const HNumber& x) 1280 { 1281 HNumber result; 1282 call1Arg(result.d, x.d, float_ln); 1283 return result; 1284 1285 } 1286 1287 /** 1288 * Returns the common logarithm of x. 1289 * If x is non positive, returns NaN. 1290 */ 1291 HNumber HMath::lg(const HNumber& x) 1292 { 1293 HNumber result; 1294 call1Arg(result.d, x.d, float_lg); 1295 return result; 1296 } 1297 1298 /** 1299 * Returns the binary logarithm of x. 1300 * If x is non positive, returns NaN. 1301 */ 1302 HNumber HMath::lb(const HNumber& x) 1303 { 1304 HNumber result; 1305 call1Arg(result.d, x.d, float_lb); 1306 return result; 1307 } 1308 1309 /** 1310 * Returns the logarithm of x to base. 1311 * If x is non positive, returns NaN. 1312 */ 1313 HNumber HMath::log(const HNumber& base, const HNumber& x) 1314 { 1315 return lg(x) / lg(base); 1316 } 1317 1318 /** 1319 * Returns the sine of x. Note that x must be in radians. 1320 */ 1321 HNumber HMath::sin(const HNumber& x) 1322 { 1323 HNumber result; 1324 call1ArgPoleCheck(result.d, x.d, float_sin); 1325 return result; 1326 } 1327 1328 /** 1329 * Returns the cosine of x. Note that x must be in radians. 1330 */ 1331 HNumber HMath::cos(const HNumber& x) 1332 { 1333 HNumber result; 1334 call1ArgPoleCheck(result.d, x.d, float_cos); 1335 return result; 1336 } 1337 1338 /** 1339 * Returns the tangent of x. Note that x must be in radians. 1340 */ 1341 HNumber HMath::tan(const HNumber& x) 1342 { 1343 HNumber result; 1344 call1ArgPoleCheck(result.d, x.d, float_tan); 1345 return result; 1346 } 1347 1348 /** 1349 * Returns the cotangent of x. Note that x must be in radians. 1350 */ 1351 HNumber HMath::cot(const HNumber& x) 1352 { 1353 return cos(x) / sin(x); 1354 } 1355 1356 /** 1357 * Returns the secant of x. Note that x must be in radians. 1358 */ 1359 HNumber HMath::sec(const HNumber& x) 1360 { 1361 return HNumber(1) / cos(x); 1362 } 1363 1364 /** 1365 * Returns the cosecant of x. Note that x must be in radians. 1366 */ 1367 HNumber HMath::csc(const HNumber& x) 1368 { 1369 return HNumber(1) / sin(x); 1370 } 1371 1372 /** 1373 * Returns the arc tangent of x. 1374 */ 1375 HNumber HMath::arctan(const HNumber& x) 1376 { 1377 HNumber result; 1378 call1Arg(result.d, x.d, float_arctan); 1379 return result; 1380 } 1381 1382 /** 1383 * Returns the angle formed by the vector (x, y) and the x-axis. 1384 */ 1385 HNumber HMath::arctan2(const HNumber& x, const HNumber& y) 1386 { 1387 if (y.isZero()) { 1388 if (x.isNegative()) 1389 return HMath::pi(); 1390 if (x.isZero()) 1391 return HMath::nan(OutOfDomain); 1392 return HNumber(0); 1393 } else { 1394 HNumber phi = HMath::arctan(HMath::abs(y / x)); 1395 if (x.isNegative()) 1396 return (HMath::pi() - phi) * HMath::sgn(y); 1397 if (x.isZero()) 1398 return HMath::pi()/HNumber(2)*HMath::sgn(y); 1399 return phi * HMath::sgn(y); 1400 } 1401 } 1402 1403 /** 1404 * Returns the arc sine of x. 1405 */ 1406 HNumber HMath::arcsin(const HNumber& x) 1407 { 1408 HNumber result; 1409 call1Arg(result.d, x.d, float_arcsin); 1410 return result; 1411 }; 1412 1413 /** 1414 * Returns the arc cosine of x. 1415 */ 1416 HNumber HMath::arccos(const HNumber& x) 1417 { 1418 HNumber result; 1419 call1Arg(result.d, x.d, float_arccos); 1420 return result; 1421 }; 1422 1423 /** 1424 * Returns the hyperbolic sine of x. 1425 */ 1426 HNumber HMath::sinh(const HNumber& x) 1427 { 1428 HNumber result; 1429 call1Arg(result.d, x.d, float_sinh); 1430 return result; 1431 } 1432 1433 /** 1434 * Returns the hyperbolic cosine of x. 1435 */ 1436 HNumber HMath::cosh(const HNumber& x) 1437 { 1438 HNumber result; 1439 call1Arg(result.d, x.d, float_cosh); 1440 return result; 1441 } 1442 1443 /** 1444 * Returns the hyperbolic tangent of x. 1445 */ 1446 HNumber HMath::tanh(const HNumber& x) 1447 { 1448 HNumber result; 1449 call1Arg(result.d, x.d, float_tanh); 1450 return result; 1451 } 1452 1453 /** 1454 * Returns the area hyperbolic sine of x. 1455 */ 1456 HNumber HMath::arsinh(const HNumber& x) 1457 { 1458 HNumber result; 1459 call1Arg(result.d, x.d, float_arsinh); 1460 return result; 1461 } 1462 1463 /** 1464 * Returns the area hyperbolic cosine of x. 1465 */ 1466 HNumber HMath::arcosh(const HNumber& x) 1467 { 1468 HNumber result; 1469 call1Arg(result.d, x.d, float_arcosh); 1470 return result; 1471 } 1472 1473 /** 1474 * Returns the area hyperbolic tangent of x. 1475 */ 1476 HNumber HMath::artanh(const HNumber& x) 1477 { 1478 HNumber result; 1479 call1Arg(result.d, x.d, float_artanh); 1480 return result; 1481 } 1482 1483 /** 1484 * Returns the Gamma function. 1485 */ 1486 HNumber HMath::gamma(const HNumber& x) 1487 { 1488 HNumber result; 1489 call1Arg(result.d, x.d, float_gamma); 1490 return result; 1491 } 1492 1493 /** 1494 * Returns ln(abs(Gamma(x))). 1495 */ 1496 HNumber HMath::lnGamma(const HNumber& x) 1497 { 1498 HNumber result; 1499 call1Arg(result.d, x.d, float_lngamma); 1500 return result; 1501 } 1502 1503 /** 1504 * Returns signum x. 1505 */ 1506 HNumber HMath::sgn(const HNumber& x) 1507 { 1508 if (x.isNan()) 1509 return HMath::nan(checkNaNParam(*x.d)); 1510 return float_getsign(&x.d->fnum); 1511 } 1512 1513 /** 1514 * Returns the binomial coefficient of n and r. 1515 * Is any of n and r negative or a non-integer, 1516 * 1/(n+1)*B(r+1, n-r+1)) is returned, where 1517 * B(x,y) is the complete Beta function 1518 */ 1519 HNumber HMath::nCr(const HNumber& n, const HNumber& r) 1520 { 1521 Error error = checkNaNParam(*n.d, r.d); 1522 if (error != Success) 1523 return HMath::nan(error); 1524 1525 if (r.isInteger() && r < 0) return HNumber(0); 1526 1527 // use symmetry nCr(n, r) == nCr(n, n-r) to find r1 such 1528 // 2*r1 <= n and nCr(n, r) == nCr(n, r1) 1529 HNumber r1 = (r + r > n) ? n - r : r; 1530 HNumber r2 = n - r1; 1531 1532 if (r1 >= 0) { 1533 if (n.isInteger() && r1.isInteger() && n <= 1000 && r1 <= 50) 1534 return factorial(n, r2+1) / factorial(r1, 1); 1535 HNumber result(n); 1536 floatnum rnum = &result.d->fnum; 1537 floatstruct fn, fr; 1538 float_create(&fn); 1539 float_create(&fr); 1540 float_copy(&fr, &r1.d->fnum, HMATH_EVAL_PREC); 1541 float_copy(&fn, rnum, EXACT); 1542 float_sub(rnum, rnum, &fr, HMATH_EVAL_PREC) 1543 && float_add(&fn, &fn, &c1, HMATH_EVAL_PREC) 1544 && float_add(&fr, &fr, &c1, HMATH_EVAL_PREC) 1545 && float_add(rnum, rnum, &c1, HMATH_EVAL_PREC) 1546 && float_lngamma(&fn, HMATH_EVAL_PREC) 1547 && float_lngamma(&fr, HMATH_EVAL_PREC) 1548 && float_lngamma(rnum, HMATH_EVAL_PREC) 1549 && float_add(rnum, rnum, &fr, HMATH_EVAL_PREC) 1550 && float_sub(rnum, &fn, rnum, HMATH_EVAL_PREC) 1551 && float_exp(rnum, HMATH_EVAL_PREC); 1552 float_free(&fn); 1553 float_free(&fr); 1554 roundSetError(result.d); 1555 return result; 1556 } 1557 if (r2 >= 0 || !r2.isInteger()) 1558 return factorial(n, r1+1)/factorial(r2, 1); 1559 return 0; 1560 } 1561 1562 /** 1563 * Returns the permutation of n elements chosen r elements. 1564 */ 1565 HNumber HMath::nPr(const HNumber& n, const HNumber& r) 1566 { 1567 return factorial(n, (n-r+1)); 1568 } 1569 1570 /** 1571 * Returns the falling Pochhammer symbol x*(x-1)*..*base. 1572 * For base == 1, this is the usual factorial x!, what this 1573 * function is named after. 1574 * This function has been extended using the Gamma function, 1575 * so that actually Gamma(x+1)/Gamma(base) is computed, a 1576 * value that equals the falling Pochhammer symbol, when 1577 * x - base is an integer, but allows other differences as well. 1578 */ 1579 HNumber HMath::factorial(const HNumber& x, const HNumber& base) 1580 { 1581 floatstruct tmp; 1582 if (float_cmp(&c1, &base.d->fnum) == 0) { 1583 HNumber result; 1584 call1Arg(result.d, x.d, float_factorial); 1585 return result; 1586 } 1587 float_create(&tmp); 1588 HNumber r(base); 1589 float_sub(&tmp, &x.d->fnum, &base.d->fnum, HMATH_EVAL_PREC) 1590 && float_add(&tmp, &tmp, &c1, HMATH_EVAL_PREC) 1591 && float_pochhammer(&r.d->fnum, &tmp, HMATH_EVAL_PREC); 1592 roundSetError(r.d); 1593 float_free(&tmp); 1594 return r; 1595 } 1596 1597 static bool checkpn(const HNumber& p, const HNumber& n) 1598 { 1599 return n.isInteger() && !n.isNegative() && !p.isNan() && !p.isNegative() && p <= 1; 1600 } 1601 1602 /** 1603 * Calculates the binomial discrete distribution probability mass function: 1604 * \f[X{\sim}B(n,p)\f] 1605 * \f[\Pr(X=k|n,p)={n\choose k}p^{k}(1-p)^{n-k}\f] 1606 * 1607 * \param[in] k the number of probed exact successes 1608 * \param[in] n the number of trials 1609 * \param[in] p the probability of success in a single trial 1610 * 1611 * \return the probability of exactly \p k successes, otherwise \p NaN if the 1612 * function is not defined for the specified parameters. 1613 */ 1614 HNumber HMath::binomialPmf(const HNumber& k, const HNumber& n, const HNumber& p) 1615 { 1616 if (!k.isInteger() || !checkpn(p, n)) 1617 return HMath::nan(InvalidParam); 1618 1619 HNumber result = nCr(n, k); 1620 if (result.isZero()) 1621 return result; 1622 1623 // special case: powers of zero, 0^0 == 1 in this context 1624 if (p.isInteger()) 1625 return (int)(p.isZero()? k.isZero() : n == k); 1626 1627 return result * raise(p, k) * raise(HNumber(1) - p, n - k); 1628 } 1629 1630 /** 1631 * Calculates the binomial cumulative distribution function: 1632 * \f[X{\sim}B(n,p)\f] 1633 * \f[\Pr(X \leq k|n,p)=\sum_{i=0}^{k}{n\choose i}p^{i}(1-p)^{n-i}\f] 1634 * 1635 * \param[in] k the maximum number of probed successes 1636 * \param[in] n the number of trials 1637 * \param[in] p the probability of success in a single trial 1638 * 1639 * \return the probability of up to \p k successes, otherwise \p NaN if the 1640 * function is not defined for the specified parameters. 1641 */ 1642 HNumber HMath::binomialCdf(const HNumber& k, const HNumber& n, const HNumber& p) 1643 { 1644 // FIXME: Use the regularized incomplete Beta function to avoid the potentially very expensive loop. 1645 if (!k.isInteger() || n.isNan()) 1646 return HMath::nan(); 1647 1648 // Initiates summation, checks arguments as well. 1649 HNumber summand = binomialPmf(0, n, p); 1650 if (summand.isNan()) 1651 return summand; 1652 1653 HNumber one(1); 1654 1655 // Some early out results. 1656 if (k.isNegative()) 1657 return 0; 1658 if (k >= n) 1659 return one; 1660 1661 HNumber pcompl = one - p; 1662 1663 if (p.isInteger()) 1664 return pcompl; 1665 1666 // use reflexion formula to limit summation 1667 if (k + k > n && k + one >= p * (n + one)) 1668 return one - binomialCdf(n - k - one, n, pcompl); 1669 1670 // loop adding binomialPdf 1671 HNumber result(summand); 1672 for (HNumber i(0); i < k;) { 1673 summand *= p * (n-i); 1674 i += one; 1675 summand /= pcompl * i; 1676 result += summand; 1677 } 1678 return result; 1679 } 1680 1681 /** 1682 * Calculates the expected value of a binomially distributed random variable: 1683 * \f[X{\sim}B(n,p)\f] 1684 * \f[E(X)=np\f] 1685 * 1686 * \param[in] n the number of trials 1687 * \param[in] p the probability of success in a single trial 1688 * 1689 * \return the expected value of the variable, otherwise \p NaN if the 1690 * function is not defined for the specified parameters. 1691 */ 1692 HNumber HMath::binomialMean(const HNumber& n, const HNumber& p) 1693 { 1694 if (!checkpn(p, n)) 1695 return HMath::nan(); 1696 return n * p; 1697 } 1698 1699 /** 1700 * Calculates the variance of a binomially distributed random variable: 1701 * \f[X{\sim}B(n,p)\f] 1702 * \f[Var(X)=np(1-p)\f] 1703 * 1704 * \param[in] n the number of trials 1705 * \param[in] p the probability of success in a single trial 1706 * 1707 * \return the variance of the variable, otherwise \p NaN if the 1708 * function is not defined for the specified parameters. 1709 */ 1710 HNumber HMath::binomialVariance(const HNumber& n, const HNumber& p) 1711 { 1712 return binomialMean(n, p) * (HNumber(1) - p); 1713 } 1714 1715 static bool checkNMn(const HNumber& N, const HNumber& M, const HNumber& n) 1716 { 1717 return N.isInteger() && !N.isNegative() 1718 && M.isInteger() && !M.isNegative() 1719 && n.isInteger() && !n.isNegative() 1720 && HMath::max(M, n) <= N; 1721 } 1722 1723 /** 1724 * Calculates the hypergeometric discrete distribution probability mass 1725 * function: 1726 * \f[X{\sim}H(N,M,n)\f] 1727 * \f[\Pr(X=k|N,M,n)=\frac{{M\choose k}{N-M\choose n-k}}{{N\choose n}}\f] 1728 * 1729 * \param[in] k the number of probed exact successes 1730 * \param[in] N the number of total elements 1731 * \param[in] M the number of success elements 1732 * \param[in] n the number of selected elements 1733 * 1734 * \return the probability of exactly \p k successes, otherwise \p NaN if the 1735 * function is not defined for the specified parameters. 1736 */ 1737 HNumber HMath::hypergeometricPmf(const HNumber& k, const HNumber& N, const HNumber& M, const HNumber& n) 1738 { 1739 if (!k.isInteger() || !checkNMn(N, M, n)) 1740 return HMath::nan(); 1741 return HMath::nCr(M, k) * HMath::nCr(N - M, n - k) / HMath::nCr(N, n); 1742 } 1743 1744 /** 1745 * Calculates the hypergeometric cumulative distribution function: 1746 * \f[X{\sim}H(N,M,n)\f] 1747 * \f[\Pr(X\leq k|N,M,n)= 1748 * \sum_{i=0}^{k}\frac{{M\choose k}{N-M\choose n-k}}{{N\choose n}}\f] 1749 * 1750 * \param[in] k the maximum number of probed successes 1751 * \param[in] N the number of total elements 1752 * \param[in] M the number of success elements 1753 * \param[in] n the number of selected elements 1754 * 1755 * \return the probability of up to \p k successes, otherwise \p NaN if the 1756 * function is not defined for the specified parameters. 1757 */ 1758 HNumber HMath::hypergeometricCdf(const HNumber& k, const HNumber& N, const HNumber& M, const HNumber& n) 1759 { 1760 // Lowest index of non-zero summand in loop. 1761 HNumber c = M + n - N; 1762 HNumber i = max(c, 0); 1763 1764 // First summand in loop, do the parameter checking here. 1765 HNumber summand = HMath::hypergeometricPmf(i, N, M, n); 1766 if (!k.isInteger() || summand.isNan()) 1767 return HMath::nan(); 1768 1769 // Some early out results. 1770 HNumber one(1); 1771 if (k >= M || k >= n) 1772 return one; 1773 if (i > k) 1774 return 0; 1775 1776 // Use reflexion formula to limit summations. Numerically unstable where the result is near 0, disable for now. 1777 // if (k + k > n) 1778 // return one - hypergeometricCdf(n - k - 1, N, N - M, n); 1779 1780 HNumber result = summand; 1781 for (; i < k;) { 1782 summand *= (M - i) * (n - i); 1783 i += one; 1784 summand /= i * (i - c); 1785 result += summand; 1786 } 1787 return result; 1788 } 1789 1790 /** 1791 * Calculates the expected value of a hypergeometrically distributed random 1792 * variable: 1793 * \f[X{\sim}H(N,M,n)\f] 1794 * \f[E(X)=n\frac{M}{N}\f] 1795 * 1796 * \param[in] N the number of total elements 1797 * \param[in] M the number of success elements 1798 * \param[in] n the number of selected elements 1799 * 1800 * \return the expected value of the variable, otherwise \p NaN if the 1801 * function is not defined for the specified parameter. 1802 */ 1803 HNumber HMath::hypergeometricMean(const HNumber& N, const HNumber& M, const HNumber& n) 1804 { 1805 if (!checkNMn(N, M, n)) 1806 return HMath::nan(); 1807 return n * M / N; 1808 } 1809 1810 /** 1811 * 1812 * Calculates the variance of a hypergeometrically distributed random variable: 1813 * \f[X{\sim}H(N,M,n)\f] 1814 * \f[Var(X)=\frac{n\frac{M}{N}(1-\frac{M}{N})(N-n)}{N-1}\f] 1815 * 1816 * \param[in] N the number of total elements 1817 * \param[in] M the number of success elements 1818 * \param[in] n the number of selected elements 1819 * 1820 * \return the variance of the variable, otherwise \p NaN if the function is 1821 * not defined for the specified parameter. 1822 */ 1823 HNumber HMath::hypergeometricVariance(const HNumber& N, const HNumber& M, const HNumber& n) 1824 { 1825 return (hypergeometricMean(N, M, n) * (HNumber(1) - M / N) * (N - n)) / (N - HNumber(1)); 1826 } 1827 1828 /** 1829 * 1830 * Calculates the poissonian discrete distribution probability mass function: 1831 * \f[X{\sim}P(\lambda)\f] 1832 * \f[\Pr(X=k|\lambda)=\frac{e^{-\lambda}\lambda^k}{k!}\f] 1833 * 1834 * \param[in] k the number of event occurrences 1835 * \param[in] l the expected number of occurrences that occur in an interval 1836 * 1837 * \return the probability of exactly \p k event occurrences, otherwise \p NaN 1838 * if the function is not defined for the specified parameters. 1839 */ 1840 HNumber HMath::poissonPmf(const HNumber& k, const HNumber& l) 1841 { 1842 if (!k.isInteger() || l.isNan() || l.isNegative()) 1843 return HMath::nan(); 1844 1845 if (k.isNegative()) 1846 return 0; 1847 if (l.isZero()) 1848 return int(k.isZero()); 1849 1850 return exp(-l) * raise(l, k) / factorial(k); 1851 } 1852 1853 /** 1854 * Calculates the poissonian cumulative distribution function: 1855 * \f[X{\sim}P(\lambda)\f] 1856 * \f[\Pr(X\leq k|\lambda)=\sum_{i=0}^{k}\frac{e^{-\lambda}\lambda^k}{k!}\f] 1857 * 1858 * \param[in] k the maximum number of event occurrences 1859 * \param[in] l the expected number of occurrences that occur in an interval 1860 * 1861 * \return the probability of up to \p k event occurrences, otherwise \p NaN 1862 * if the function is not defined for the specified parameters. 1863 */ 1864 HNumber HMath::poissonCdf(const HNumber& k, const HNumber& l) 1865 { 1866 // FIXME: Use the incomplete gamma function to avoid a potentially expensive loop. 1867 if (!k.isInteger() || l.isNan() || l.isNegative()) 1868 return HMath::nan(); 1869 1870 if (k.isNegative()) 1871 return 0; 1872 1873 HNumber one(1); 1874 if (l.isZero()) 1875 return one; 1876 1877 HNumber summand = one; 1878 HNumber result = one; 1879 for (HNumber i = one; i <= k; i += one) { 1880 summand *= l / i; 1881 result += summand; 1882 } 1883 result = exp(-l) * result; 1884 return result; 1885 } 1886 1887 /** 1888 * Calculates the expected value of a Poisson distributed random variable: 1889 * \f[X{\sim}P(\lambda)\f] 1890 * \f[E(X)=\lambda\f] 1891 * 1892 * \param[in] l the expected number of occurrences that occur in an interval 1893 * 1894 * \return the expected value of the variable, otherwise \p NaN if the 1895 * function is not defined for the specified parameter. 1896 */ 1897 HNumber HMath::poissonMean(const HNumber& l) 1898 { 1899 if (l.isNan() || l.isNegative()) 1900 return HMath::nan(); 1901 return l; 1902 } 1903 1904 /** 1905 * Calculates the variance of a Poisson distributed random variable: 1906 * \f[X{\sim}P(\lambda)\f] 1907 * \f[Var(X)=\lambda\f] 1908 * 1909 * \param[in] l the expected number of occurrences that occur in an interval 1910 * 1911 * \return the variance of the variable, otherwise \p NaN if the function is 1912 * not defined for the specified parameter. 1913 */ 1914 HNumber HMath::poissonVariance(const HNumber& l) 1915 { 1916 return poissonMean(l); 1917 } 1918 1919 /** 1920 * Returns the erf function (related to normal distribution). 1921 */ 1922 HNumber HMath::erf(const HNumber& x) 1923 { 1924 HNumber result; 1925 call1Arg(result.d, x.d, float_erf); 1926 return result; 1927 } 1928 1929 /** 1930 * Returns the complementary erf function (related to normal distribution). 1931 */ 1932 HNumber HMath::erfc(const HNumber& x) 1933 { 1934 HNumber result; 1935 call1Arg(result.d, x.d, float_erfc); 1936 return result; 1937 } 1938 1939 /** 1940 * Restricts a logic value to a given bit size. 1941 */ 1942 HNumber HMath::mask(const HNumber& val, const HNumber& bits) 1943 { 1944 if (val.isNan() || bits == 0 || bits >= LOGICRANGE || !bits.isInteger()) 1945 return HMath::nan(); 1946 return val & ~(HNumber(-1) << HNumber(bits)); 1947 } 1948 1949 /** 1950 * sign-extends an unsigned value 1951 */ 1952 HNumber HMath::sgnext(const HNumber& val, const HNumber& bits) 1953 { 1954 if (val.isNan() || bits == 0 || bits >= LOGICRANGE || !bits.isInteger()) 1955 return HMath::nan(); 1956 HNumber ofs = HNumber(LOGICRANGE) - bits; 1957 return (val << ofs) >> ofs; 1958 } 1959 1960 /** 1961 * For bits >= 0 does an arithmetic shift right, for bits < 0 a shift left. 1962 */ 1963 HNumber HMath::ashr(const HNumber& val, const HNumber& bits) 1964 { 1965 if (val.isNan() || bits <= -LOGICRANGE || bits >= LOGICRANGE || !bits.isInteger()) 1966 return HMath::nan(); 1967 if (bits >= 0) 1968 return val >> bits; 1969 return val << -bits; 1970 } 1971 1972 /** 1973 * Decode an IEEE-754 bit pattern with the default exponent bias 1974 */ 1975 HNumber HMath::decodeIeee754(const HNumber& val, const HNumber& exp_bits, const HNumber& significand_bits) 1976 { 1977 return HMath::decodeIeee754(val, exp_bits, significand_bits, HMath::raise(2, exp_bits - 1) - 1); 1978 } 1979 1980 /** 1981 * Decode an IEEE-754 bit pattern with the given parameters 1982 */ 1983 HNumber HMath::decodeIeee754(const HNumber& val, const HNumber& exp_bits, const HNumber& significand_bits, 1984 const HNumber& exp_bias) 1985 { 1986 if (val.isNan() 1987 || exp_bits <= 0 || exp_bits >= LOGICRANGE || !exp_bits.isInteger() 1988 || significand_bits <= 0 || significand_bits >= LOGICRANGE || !significand_bits.isInteger() 1989 || !exp_bias.isInteger()) 1990 return HMath::nan(); 1991 1992 HNumber sign(HMath::mask(val >> (exp_bits + significand_bits), 1).isZero() ? 1 : -1); 1993 HNumber exp = HMath::mask(val >> significand_bits, exp_bits); 1994 // <=> '0.' b_x b_x-1 b_x-2 ... b_0 1995 HNumber significand = HMath::mask(val, significand_bits) * HMath::raise(2, -significand_bits); 1996 1997 if (exp.isZero()) { 1998 // Exponent 0, subnormal value or zero. 1999 return sign * significand * HMath::raise(2, exp - exp_bias + 1); 2000 } 2001 if (exp - HMath::raise(2, exp_bits) == -1) { 2002 // Exponent all 1... 2003 if (significand.isZero()) 2004 // ...and signficand 0, infinity. 2005 // TODO: Represent infinity as something other than NaN? 2006 return HNumber(); 2007 // ...and significand not 0, NaN. 2008 return HMath::nan(); 2009 } 2010 return sign * (significand + 1) * HMath::raise(2, exp - exp_bias); // Normalised value. 2011 } 2012 2013 /** 2014 * Encode a value in a IEEE-754 binary representation with the default exponent bias 2015 */ 2016 HNumber HMath::encodeIeee754(const HNumber& val, const HNumber& exp_bits, const HNumber& significand_bits) 2017 { 2018 return HMath::encodeIeee754(val, exp_bits, significand_bits, HMath::raise(2, exp_bits - 1) - 1); 2019 } 2020 2021 /** 2022 * Encode a value in a IEEE-754 binary representation 2023 */ 2024 HNumber HMath::encodeIeee754(const HNumber& val, const HNumber& exp_bits, const HNumber& significand_bits, 2025 const HNumber& exp_bias) 2026 { 2027 if (exp_bits <= 0 || exp_bits >= LOGICRANGE || !exp_bits.isInteger() 2028 || significand_bits <= 0 || significand_bits >= LOGICRANGE || !significand_bits.isInteger() 2029 || !exp_bias.isInteger()) 2030 return HMath::nan(); 2031 2032 HNumber sign_bit; 2033 HNumber significand; 2034 HNumber exponent; 2035 2036 HNumber min_exp(1 - exp_bias); 2037 HNumber max_exp(HMath::raise(2, exp_bits) - 2 - exp_bias); 2038 2039 if (val.isNan()) { 2040 // Encode a NaN. 2041 sign_bit = 0; 2042 significand = HMath::raise(2, significand_bits) - 1; 2043 exponent = HMath::raise(2, exp_bits) - 1; 2044 } else if (val.isZero()) { 2045 // Encode a basic 0. 2046 sign_bit = 0; 2047 significand = 0; 2048 exponent = 0; 2049 } else { 2050 // Regular input value. 2051 sign_bit = val.isNegative() ? 1 : 0; 2052 // Determine exponent. 2053 HNumber search_min = min_exp; 2054 HNumber search_max = max_exp; 2055 exponent = HMath::ceil((search_max - search_min) / 2) + search_min; 2056 significand = HMath::abs(val) * HMath::raise(2, -exponent); 2057 2058 do { 2059 if (significand >= 1 && significand < 2) { 2060 // Integer part is 1, stop here. 2061 break; 2062 } else if (significand >= 2) { 2063 // Increase exponent. 2064 search_min = exponent + 1; 2065 } else if (significand < 1) { 2066 // Decrease exponent. 2067 search_max = exponent - 1; 2068 } 2069 exponent = HMath::ceil((search_max - search_min) / 2) + search_min; 2070 significand = HMath::abs(val) * HMath::raise(2, -exponent); 2071 } while (exponent != min_exp && exponent != max_exp); 2072 2073 HNumber rounded = HMath::round(significand * HMath::raise(2, significand_bits)); 2074 HNumber intpart = HMath::integer(rounded * HMath::raise(2, -significand_bits)); 2075 significand = HMath::mask(rounded, significand_bits); 2076 if (intpart.isZero()) { 2077 // Subnormal value. 2078 exponent = 0; 2079 } else if (intpart > 1) { 2080 // Infinity. 2081 exponent = HMath::raise(2, exp_bits) - 1; 2082 significand = 0; 2083 } else { 2084 // Normalised value. 2085 exponent = exponent + exp_bias; 2086 } 2087 } 2088 2089 HNumber result = sign_bit << (exp_bits + significand_bits) | exponent << (significand_bits) | significand; 2090 return result; 2091 } 2092 2093 std::ostream& operator<<(std::ostream& s, const HNumber& n) 2094 { 2095 QString str = HMath::format(n); 2096 s << str.toLatin1().constData(); 2097 return s; 2098 } 2099 2100 struct MathInit { 2101 MathInit(){ floatmath_init(); } 2102 }; 2103 2104 MathInit mathinit; 2105 2106 /** 2107 * Parses a string containing a real number. 2108 * 2109 * Parameters : 2110 * str_in : pointer towards the string to parse 2111 * str_out : pointer towards a pointer towards the remaining of the string after parsing 2112 */ 2113 HNumber HMath::parse_str(const char* str_in, const char** str_out) { 2114 2115 // FIXME: Duplicate code. 2116 // FIXME: Error management. 2117 2118 const char* str = str_in; 2119 t_itokens tokens; 2120 2121 HNumber x; 2122 delete x.d; 2123 2124 x.d = new HNumberPrivate; 2125 if ((x.d->error = parse(&tokens, &str)) == Success) 2126 x.d->error = float_in(&x.d->fnum, &tokens); 2127 float_geterror(); 2128 2129 /* Store remaining of the string */ 2130 if (str_out) 2131 *str_out = str; 2132 2133 return x; 2134 } 2135 2136 bool HNumber::isNearZero() const 2137 { 2138 return float_iszero(&(d->fnum)) || float_getexponent(&(d->fnum)) <= -80; 2139 }