/source/Real.cpp

https://github.com/denprog/BigNumbersParser · C++ · 2046 lines · 1029 code · 355 blank · 662 comment · 290 complexity · 9518f738564d58f077aadea9439d99c2 MD5 · raw file

  1. #include "stdafx.h"
  2. #include "Real.h"
  3. namespace BigNumbersParser
  4. {
  5. Real pi(const int precision);
  6. /**
  7. * Default constructor.
  8. */
  9. Real::Real()
  10. {
  11. mpfr_init2(number, mpfr_get_default_prec());
  12. mpfr_set_si(number, 0, GMP_RNDN);
  13. #ifdef TRACE_OUTPUT
  14. UpdateNumberStr();
  15. #endif
  16. }
  17. /**
  18. * Constructor.
  19. * @param precision The precision.
  20. */
  21. Real::Real(int precision)
  22. {
  23. mpfr_init2(number, max((int)mpfr_get_default_prec(), precision));
  24. //mpfr_init2(number, precision);
  25. mpfr_set_si(number, 0, GMP_RNDN);
  26. //addPrecision = 0;
  27. #ifdef TRACE_OUTPUT
  28. UpdateNumberStr();
  29. #endif
  30. }
  31. /**
  32. * Constructor from char*.
  33. * @param precision The precision.
  34. * @param num The number.
  35. */
  36. Real::Real(int precision, const char* num)
  37. {
  38. mpfr_init2(number, max((int)mpfr_get_default_prec(), precision));
  39. //mpfr_init2(number, strlen(num) + 1);
  40. mpfr_set_str(number, num, DEFAULT_BASE, MPFR_RNDZ);
  41. stringNumber = num;
  42. //mpfr_prec_round(number, precision / 2, GMP_RNDN);
  43. //addPrecision = (int)strchr(num, '.');
  44. //if (!addPrecision)
  45. // addPrecision = strlen(num);
  46. //else
  47. // addPrecision -= (int)num;
  48. #ifdef TRACE_OUTPUT
  49. UpdateNumberStr();
  50. #endif
  51. }
  52. /**
  53. * Constructor from int.
  54. * @param precision The precision.
  55. * @param num The number.
  56. */
  57. Real::Real(int precision, int num)
  58. {
  59. mpfr_init2(number, max((int)mpfr_get_default_prec(), precision));
  60. //mpfr_init2(number, precision);
  61. mpfr_set_si(number, num, GMP_RNDN);
  62. //addPrecision = 1;
  63. #ifdef TRACE_OUTPUT
  64. UpdateNumberStr();
  65. #endif
  66. }
  67. /**
  68. * Constructor from float.
  69. * @param precision The precision.
  70. * @param num The number.
  71. */
  72. Real::Real(int precision, float num)
  73. {
  74. mpfr_init2(number, max((int)mpfr_get_default_prec(), precision));
  75. //mpfr_init2(number, precision);
  76. mpfr_set_d(number, num, GMP_RNDN);
  77. //addPrecision = 1;
  78. #ifdef TRACE_OUTPUT
  79. UpdateNumberStr();
  80. #endif
  81. }
  82. /**
  83. * Constructor from string.
  84. * @param num The number.
  85. */
  86. Real::Real(const string& num)
  87. {
  88. stringNumber = num;
  89. mpfr_init2(number, max((int)mpfr_get_default_prec(), MathHelper::ToBitPrecision(num.length() * 2)) + 1);
  90. mpfr_set_str(number, num.c_str(), DEFAULT_BASE, MPFR_RNDA);
  91. SetPrecision(GetPrecision() + GetExp());
  92. #ifdef TRACE_OUTPUT
  93. UpdateNumberStr();
  94. #endif
  95. }
  96. /**
  97. * Copy constructor.
  98. * @param source The source number.
  99. */
  100. Real::Real(const Real& source)
  101. {
  102. mpfr_init2(number, source.GetBitPrecision());
  103. mpfr_set(number, source.number, GMP_RNDN);
  104. //addPrecision = source.addPrecision;
  105. stringNumber = source.stringNumber;
  106. #ifdef TRACE_OUTPUT
  107. UpdateNumberStr();
  108. #endif
  109. }
  110. /**
  111. * Destructor.
  112. */
  113. Real::~Real()
  114. {
  115. mpfr_clear(number);
  116. }
  117. /**
  118. * = operator.
  119. * @param source Source for the number.
  120. * @return The result number.
  121. */
  122. Real& Real::operator=(const Real& source)
  123. {
  124. if (this == &source)
  125. return *this;
  126. mpfr_clear(number);
  127. mpfr_init2(number, source.GetBitPrecision());
  128. mpfr_set(number, source.number, GMP_RNDN);
  129. //addPrecision = source.addPrecision;
  130. stringNumber = source.stringNumber;
  131. #ifdef TRACE_OUTPUT
  132. UpdateNumberStr();
  133. #endif
  134. return *this;
  135. }
  136. /**
  137. * = operator from int.
  138. * @param num The number.
  139. * @return The result number.
  140. */
  141. Real& Real::operator=(const int num)
  142. {
  143. mpfr_set_si(number, num, GMP_RNDN);
  144. //addPrecision = 1;
  145. #ifdef TRACE_OUTPUT
  146. UpdateNumberStr();
  147. #endif
  148. return *this;
  149. }
  150. /**
  151. * = operator from double.
  152. * @param num The number.
  153. * @return The result number.
  154. */
  155. Real& Real::operator=(const double num)
  156. {
  157. mpfr_set_d(number, num, GMP_RNDN);
  158. //addPrecision = 1;
  159. #ifdef TRACE_OUTPUT
  160. UpdateNumberStr();
  161. #endif
  162. return *this;
  163. }
  164. /**
  165. * = operator from char*.
  166. * @param num The number.
  167. * @return The result number.
  168. */
  169. Real& Real::operator=(const char* num)
  170. {
  171. mpfr_t t;
  172. mpfr_init2(t, GetBitPrecision());
  173. if (mpfr_set_str(t, num, DEFAULT_BASE, GMP_RNDN) == 0)
  174. {
  175. mpfr_set(number, t, GMP_RNDN);
  176. mpfr_clear(t);
  177. }
  178. else
  179. {
  180. mpfr_clear(t);
  181. }
  182. stringNumber = num;
  183. #ifdef TRACE_OUTPUT
  184. UpdateNumberStr();
  185. #endif
  186. return *this;
  187. }
  188. /**
  189. * = operator from std::string.
  190. * @param num The number.
  191. * @return The result number.
  192. */
  193. Real& Real::operator=(const string& num)
  194. {
  195. mpfr_t t;
  196. if ((int)num.length() + 1 > GetPrecision())
  197. {
  198. SetBitPrecision(MathHelper::ToBitPrecision(num.length() * 2));
  199. mpfr_init2(t, GetBitPrecision());
  200. }
  201. else
  202. mpfr_init2(t, GetBitPrecision());
  203. if (mpfr_set_str(t, num.c_str(), DEFAULT_BASE, GMP_RNDN) == 0)
  204. {
  205. mpfr_set(number, t, GMP_RNDN);
  206. mpfr_clear(t);
  207. }
  208. else
  209. {
  210. mpfr_clear(t);
  211. }
  212. stringNumber = num;
  213. #ifdef TRACE_OUTPUT
  214. UpdateNumberStr();
  215. #endif
  216. return *this;
  217. }
  218. /**
  219. * + operator.
  220. * @return The result number.
  221. */
  222. Real Real::operator+()
  223. {
  224. return *this;
  225. }
  226. /**
  227. * - operator.
  228. * @return The result number.
  229. */
  230. Real Real::operator-()
  231. {
  232. Real res(GetBitPrecision());
  233. mpfr_neg(res.number, number, GMP_RNDN);
  234. return res;
  235. }
  236. /**
  237. * ++ operator.
  238. * @return The result number.
  239. */
  240. Real Real::operator++()
  241. {
  242. *this += 1;
  243. return *this;
  244. }
  245. /**
  246. * -- operator.
  247. * @return The result number.
  248. */
  249. Real Real::operator--()
  250. {
  251. *this -= 1;
  252. return *this;
  253. }
  254. /**
  255. * Addition operator.
  256. * @exception MathException Thrown when the mathematics error condition occurs.
  257. * @param num1 The first value.
  258. * @param num2 A value to add to it.
  259. * @return The result of the operation.
  260. */
  261. Real operator+(const Real& num1, const Real& num2)
  262. {
  263. Real res(max(num1.GetBitPrecision() + 2, num2.GetBitPrecision()) + 2);
  264. while (mpfr_add(res.number, num1.number, num2.number, DEFAULT_RND) != 0)
  265. {
  266. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  267. throw MathException(Overflow);
  268. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  269. }
  270. return res;
  271. }
  272. /**
  273. * Addition operator.
  274. * @exception MathException Thrown when the mathematics error condition occurs.
  275. * @param num1 The first value.
  276. * @param num2 A value to add to it.
  277. * @return The result of the operation.
  278. */
  279. Real operator+(const Real& num1, const int num2)
  280. {
  281. Real res(num1.GetBitPrecision());
  282. while (mpfr_add_si(res.number, num1.number, num2, DEFAULT_RND) != 0)
  283. {
  284. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  285. throw MathException(Overflow);
  286. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  287. }
  288. return res;
  289. }
  290. /**
  291. * Addition operator.
  292. * @exception MathException Thrown when the mathematics error condition occurs.
  293. * @param num1 The first value.
  294. * @param num2 A value to add to it.
  295. * @return The result of the operation.
  296. */
  297. Real operator+(const int num1, const Real& num2)
  298. {
  299. Real res(num2.GetBitPrecision());
  300. while (mpfr_add_si(res.number, num2.number, num1, DEFAULT_RND) != 0)
  301. {
  302. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  303. throw MathException(Overflow);
  304. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  305. }
  306. return res;
  307. }
  308. /**
  309. * Addition operator.
  310. * @exception MathException Thrown when the mathematics error condition occurs.
  311. * @param num1 The first value.
  312. * @param num2 A value to add to it.
  313. * @return The result of the operation.
  314. */
  315. Real operator+(const Real& num1, const float num2)
  316. {
  317. Real res(num1.GetBitPrecision());
  318. while (mpfr_add_d(res.number, num1.number, num2, DEFAULT_RND) != 0)
  319. {
  320. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  321. throw MathException(Overflow);
  322. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  323. }
  324. return res;
  325. }
  326. /**
  327. * Addition operator.
  328. * @exception MathException Thrown when the mathematics error condition occurs.
  329. * @param num1 The first value.
  330. * @param num2 A value to add to it.
  331. * @return The result of the operation.
  332. */
  333. Real operator+(const float num1, const Real& num2)
  334. {
  335. Real res(num2.GetBitPrecision());
  336. while (mpfr_add_d(res.number, num2.number, num1, DEFAULT_RND) != 0)
  337. {
  338. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  339. throw MathException(Overflow);
  340. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  341. }
  342. return res;
  343. }
  344. /**
  345. * Subtraction operator.
  346. * @param num1 The first value.
  347. * @param num2 A value to subtract from it.
  348. * @return The result of the operation.
  349. */
  350. Real operator-(const Real& num1, const Real& num2)
  351. {
  352. Real res(max(num1.GetBitPrecision(), num2.GetBitPrecision()) + 1);
  353. mpfr_sub(res.number, num1.number, num2.number, GMP_RNDN);
  354. #ifdef TRACE_OUTPUT
  355. res.UpdateNumberStr();
  356. #endif
  357. return res;
  358. }
  359. /**
  360. * Subtraction operator.
  361. * @param num1 The first value.
  362. * @param num2 A value to subtract from it.
  363. * @return The result of the operation.
  364. */
  365. Real operator-(const Real& num1, const int num2)
  366. {
  367. Real res(num1.GetBitPrecision());
  368. mpfr_sub_si(res.number, num1.number, num2, DEFAULT_RND);
  369. return res;
  370. }
  371. /**
  372. * Subtraction operator.
  373. * @param num1 The first value.
  374. * @param num2 A value to subtract from it.
  375. * @return The result of the operation.
  376. */
  377. Real operator-(const int num1, const Real& num2)
  378. {
  379. Real res(num2.GetBitPrecision());
  380. mpfr_si_sub(res.number, num1, num2.number, DEFAULT_RND);
  381. return res;
  382. }
  383. /**
  384. * Subtraction operator.
  385. * @param num1 The first value.
  386. * @param num2 A value to subtract from it.
  387. * @return The result of the operation.
  388. */
  389. Real operator-(const Real& num1, const float num2)
  390. {
  391. Real res(num1.GetBitPrecision());
  392. mpfr_sub_d(res.number, num1.number, num2, DEFAULT_RND);
  393. return res;
  394. }
  395. /**
  396. * Subtraction operator.
  397. * @param num1 The first value.
  398. * @param num2 A value to subtract from it.
  399. * @return The result of the operation.
  400. */
  401. Real operator-(const float num1, const Real& num2)
  402. {
  403. Real res(num2.GetBitPrecision());
  404. mpfr_d_sub(res.number, num1, num2.number, DEFAULT_RND);
  405. return res;
  406. }
  407. /**
  408. * Multiplication operator.
  409. * @exception MathException Thrown when the mathematics error condition occurs.
  410. * @param num1 The first value to multiply.
  411. * @param num2 The second value to multiply.
  412. * @return The result of the operation.
  413. */
  414. Real operator*(const Real& num1, const Real& num2)
  415. {
  416. Real res(max(num1.GetBitPrecision() * 2, num2.GetBitPrecision()) * 2);
  417. while (mpfr_mul(res.number, num1.number, num2.number, DEFAULT_RND) != 0)
  418. {
  419. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  420. throw MathException(Overflow);
  421. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  422. }
  423. return res;
  424. }
  425. /**
  426. * Multiplication operator.
  427. * @exception MathException Thrown when the mathematics error condition occurs.
  428. * @param num1 The first value to multiply.
  429. * @param num2 The second value to multiply.
  430. * @return The result of the operation.
  431. */
  432. Real operator*(const Real& num1, const int num2)
  433. {
  434. Real res(num1.GetBitPrecision());
  435. while (mpfr_mul_si(res.number, num1.number, num2, DEFAULT_RND) != 0)
  436. {
  437. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  438. throw MathException(Overflow);
  439. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  440. }
  441. return res;
  442. }
  443. /**
  444. * Multiplication operator.
  445. * @exception MathException Thrown when the mathematics error condition occurs.
  446. * @param num1 The first value to multiply.
  447. * @param num2 The second value to multiply.
  448. * @return The result of the operation.
  449. */
  450. Real operator*(const int num1, const Real& num2)
  451. {
  452. Real res(num2.GetBitPrecision());
  453. while (mpfr_mul_si(res.number, num2.number, num1, DEFAULT_RND) != 0)
  454. {
  455. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  456. throw MathException(Overflow);
  457. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  458. }
  459. return res;
  460. }
  461. /**
  462. * Multiplication operator.
  463. * @exception MathException Thrown when the mathematics error condition occurs.
  464. * @param num1 The first value to multiply.
  465. * @param num2 The second value to multiply.
  466. * @return The result of the operation.
  467. */
  468. Real operator*(const Real& num1, const float num2)
  469. {
  470. Real res(num1.GetBitPrecision());
  471. while (mpfr_mul_d(res.number, num1.number, num2, DEFAULT_RND) != 0)
  472. {
  473. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  474. throw MathException(Overflow);
  475. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  476. }
  477. return res;
  478. }
  479. /**
  480. * Multiplication operator.
  481. * @exception MathException Thrown when the mathematics error condition occurs.
  482. * @param num1 The first value to multiply.
  483. * @param num2 The second value to multiply.
  484. * @return The result of the operation.
  485. */
  486. Real operator*(const float num1, const Real& num2)
  487. {
  488. Real res(num2.GetBitPrecision());
  489. while (mpfr_mul_d(res.number, num2.number, num1, DEFAULT_RND) != 0)
  490. {
  491. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  492. throw MathException(Overflow);
  493. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  494. }
  495. return res;
  496. }
  497. /**
  498. * Division operator.
  499. * @exception MathException Thrown when the mathematics error condition occurs.
  500. * @param num1 The numerator.
  501. * @param num2 The denominator.
  502. * @return The result of the operation.
  503. */
  504. Real operator/(const Real& num1, const Real& num2)
  505. {
  506. Real res(max(num1.GetBitPrecision() + 2, num2.GetBitPrecision() + 2));
  507. mpfr_div(res.number, num1.number, num2.number, GMP_RNDN);
  508. if (res.IsInfinity() || res.IsNaN())
  509. throw MathException(DivisionByZero);
  510. #ifdef TRACE_OUTPUT
  511. res.UpdateNumberStr();
  512. #endif
  513. return res;
  514. }
  515. /**
  516. * Division operator.
  517. * @exception MathException Thrown when the mathematics error condition occurs.
  518. * @param num1 The numerator.
  519. * @param num2 The denominator.
  520. * @return The result of the operation.
  521. */
  522. Real operator/(const Real& num1, const int num2)
  523. {
  524. Real res(num1.GetBitPrecision());
  525. mpfr_div_si(res.number, num1.number, num2, DEFAULT_RND);
  526. if (res.IsInfinity() || res.IsNaN())
  527. throw MathException(Overflow);
  528. return res;
  529. }
  530. /**
  531. * Division operator.
  532. * @exception MathException Thrown when the mathematics error condition occurs.
  533. * @param num1 The numerator.
  534. * @param num2 The denominator.
  535. * @return The result of the operation.
  536. */
  537. Real operator/(const int num1, const Real& num2)
  538. {
  539. Real res(num2.GetBitPrecision());
  540. mpfr_si_div(res.number, num1, num2.number, DEFAULT_RND);
  541. if (res.IsInfinity() || res.IsNaN())
  542. throw MathException(Overflow);
  543. return res;
  544. }
  545. /**
  546. * Division operator.
  547. * @exception MathException Thrown when the mathematics error condition occurs.
  548. * @param num1 The numerator.
  549. * @param num2 The denominator.
  550. * @return The result of the operation.
  551. */
  552. Real operator/(const Real& num1, const float num2)
  553. {
  554. Real res(num1.GetBitPrecision());
  555. mpfr_div_d(res.number, num1.number, num2, DEFAULT_RND);
  556. if (res.IsInfinity() || res.IsNaN())
  557. throw MathException(Overflow);
  558. return res;
  559. }
  560. /**
  561. * Division operator.
  562. * @exception MathException Thrown when the mathematics error condition occurs.
  563. * @param num1 The numerator.
  564. * @param num2 The denominator.
  565. * @return The result of the operation.
  566. */
  567. Real operator/(const float num1, const Real& num2)
  568. {
  569. Real res(num2.GetBitPrecision());
  570. mpfr_d_div(res.number, num1, num2.number, DEFAULT_RND);
  571. if (res.IsInfinity() || res.IsNaN())
  572. throw MathException(Overflow);
  573. return res;
  574. }
  575. /**
  576. * += operator.
  577. * @param num A value to add to it.
  578. */
  579. void Real::operator+=(const Real& num)
  580. {
  581. *this = *this + num;
  582. }
  583. /**
  584. * += operator.
  585. * @param num A value to add to it.
  586. */
  587. void Real::operator+=(const int num)
  588. {
  589. *this = *this + num;
  590. }
  591. /**
  592. * += operator.
  593. * @param num A value to add to it.
  594. */
  595. void Real::operator+=(const float num)
  596. {
  597. *this = *this + num;
  598. }
  599. /**
  600. * -= operator.
  601. * @param num A value to subtract from it.
  602. */
  603. void Real::operator-=(const Real& num)
  604. {
  605. *this = *this - num;
  606. }
  607. /**
  608. * -= operator.
  609. * @param num A value to subtract from it.
  610. */
  611. void Real::operator-=(const int num)
  612. {
  613. *this = *this - num;
  614. }
  615. /**
  616. * -= operator.
  617. * @param num A value to subtract from it.
  618. */
  619. void Real::operator-=(const float num)
  620. {
  621. *this = *this - num;
  622. }
  623. /**
  624. * *= operator.
  625. * @param num A value to multiply.
  626. */
  627. void Real::operator*=(const Real& num)
  628. {
  629. *this = *this * num;
  630. }
  631. /**
  632. * *= operator.
  633. * @param num A value to multiply.
  634. */
  635. void Real::operator*=(const int num)
  636. {
  637. *this = *this * num;
  638. }
  639. /**
  640. * *= operator.
  641. * @param num A value to multiply.
  642. */
  643. void Real::operator*=(const float num)
  644. {
  645. *this = *this * num;
  646. }
  647. /**
  648. * /= operator.
  649. * @param num The denominator.
  650. */
  651. void Real::operator/=(const Real& num)
  652. {
  653. *this = *this / num;
  654. }
  655. /**
  656. * /= operator.
  657. * @param num The denominator.
  658. */
  659. void Real::operator/=(const int num)
  660. {
  661. *this = *this / num;
  662. }
  663. /**
  664. * /= operator.
  665. * @param num The denominator.
  666. */
  667. void Real::operator/=(const float num)
  668. {
  669. *this = *this / num;
  670. }
  671. /**
  672. * Gets the int.
  673. * @exception MathException Thrown when the mathematics error condition occurs.
  674. * @return number of type int.
  675. */
  676. Real::operator int() const
  677. {
  678. if (IsInteger())
  679. return mpfr_get_si(number, DEFAULT_RND);
  680. else
  681. throw MathException(ConversionDoesNotFit);
  682. }
  683. /**
  684. * Equality operator.
  685. * @exception MathException Thrown when the mathematics error condition occurs.
  686. * @param num1 The first instance to compare.
  687. * @param num2 The second instance to compare.
  688. * @return true if the parameters are considered equivalent.
  689. */
  690. bool operator==(const Real& num1, const Real& num2)
  691. {
  692. if (num1.IsNaN() || num2.IsNaN())
  693. throw MathException(Overflow);
  694. return mpfr_equal_p(num1.number, num2.number) != 0;
  695. }
  696. /**
  697. * Equality operator.
  698. * @exception MathException Thrown when the mathematics error condition occurs.
  699. * @param num1 The first instance to compare.
  700. * @param num2 The second instance to compare.
  701. * @return true if the parameters are considered equivalent.
  702. */
  703. bool operator==(const Real& num1, const int num2)
  704. {
  705. if (num1.IsNaN())
  706. throw MathException(Overflow);
  707. return mpfr_cmp_si(num1.number, num2) == 0;
  708. }
  709. /**
  710. * Equality operator.
  711. * @exception MathException Thrown when the mathematics error condition occurs.
  712. * @param num1 The first instance to compare.
  713. * @param num2 The second instance to compare.
  714. * @return true if the parameters are considered equivalent.
  715. */
  716. bool operator==(const int num1, const Real& num2)
  717. {
  718. if (num2.IsNaN())
  719. throw MathException(Overflow);
  720. return mpfr_cmp_si(num2.number, num1) == 0;
  721. }
  722. /**
  723. * Equality operator.
  724. * @exception MathException Thrown when the mathematics error condition occurs.
  725. * @param num1 The first instance to compare.
  726. * @param num2 The second instance to compare.
  727. * @return true if the parameters are considered equivalent.
  728. */
  729. bool operator==(const Real& num1, const float num2)
  730. {
  731. if (num1.IsNaN())
  732. throw MathException(Overflow);
  733. return mpfr_cmp_d(num1.number, num2) == 0;
  734. }
  735. /**
  736. * Equality operator.
  737. * @exception MathException Thrown when the mathematics error condition occurs.
  738. * @param num1 The first instance to compare.
  739. * @param num2 The second instance to compare.
  740. * @return true if the parameters are considered equivalent.
  741. */
  742. bool operator==(const float num1, const Real& num2)
  743. {
  744. if (num2.IsNaN())
  745. throw MathException(Overflow);
  746. return mpfr_cmp_d(num2.number, num1) == 0;
  747. }
  748. /**
  749. * Equality operator.
  750. * @exception MathException Thrown when the mathematics error condition occurs.
  751. * @param num1 The first instance to compare.
  752. * @param num2 The second instance to compare.
  753. * @return true if the parameters are considered equivalent.
  754. */
  755. bool operator==(const Real& num1, const double num2)
  756. {
  757. if (num1.IsNaN())
  758. throw MathException(Overflow);
  759. return mpfr_cmp_d(num1.number, num2) == 0;
  760. }
  761. /**
  762. * Equality operator.
  763. * @exception MathException Thrown when the mathematics error condition occurs.
  764. * @param num1 The first instance to compare.
  765. * @param num2 The second instance to compare.
  766. * @return true if the parameters are considered equivalent.
  767. */
  768. bool operator==(const double num1, const Real& num2)
  769. {
  770. if (num2.IsNaN())
  771. throw MathException(Overflow);
  772. return mpfr_cmp_d(num2.number, num1) == 0;
  773. }
  774. /**
  775. * Equality operator.
  776. * @param num1 The first instance to compare.
  777. * @param num2 The second instance to compare.
  778. * @return true if the parameters are considered equivalent.
  779. */
  780. bool operator==(const Real& num1, const char* num2)
  781. {
  782. return num1 == Real(num1.GetBitPrecision(), num2);
  783. }
  784. /**
  785. * Equality operator.
  786. * @param num1 The first instance to compare.
  787. * @param num2 The second instance to compare.
  788. * @return true if the parameters are considered equivalent.
  789. */
  790. bool operator==(const char* num1, const Real& num2)
  791. {
  792. return Real(num2.GetBitPrecision(), num1) == num2;
  793. }
  794. /**
  795. * Not equality operator.
  796. * @exception MathException Thrown when the mathematics error condition occurs.
  797. * @param num1 The first instance to compare.
  798. * @param num2 The second instance to compare.
  799. * @return true if the parameters are not considered equivalent.
  800. */
  801. bool operator!=(const Real& num1, const Real& num2)
  802. {
  803. if (num1.IsNaN() || num2.IsNaN())
  804. throw MathException(Overflow);
  805. return mpfr_equal_p(num1.number, num2.number) == 0;
  806. }
  807. /**
  808. * Not equality operator.
  809. * @exception MathException Thrown when the mathematics error condition occurs.
  810. * @param num1 The first instance to compare.
  811. * @param num2 The second instance to compare.
  812. * @return true if the parameters are not considered equivalent.
  813. */
  814. bool operator!=(const Real& num1, const int num2)
  815. {
  816. if (num1.IsNaN())
  817. throw MathException(Overflow);
  818. return mpfr_cmp_si(num1.number, num2) != 0;
  819. }
  820. /**
  821. * Not equality operator.
  822. * @exception MathException Thrown when the mathematics error condition occurs.
  823. * @param num1 The first instance to compare.
  824. * @param num2 The second instance to compare.
  825. * @return true if the parameters are not considered equivalent.
  826. */
  827. bool operator!=(const int num1, const Real& num2)
  828. {
  829. if (num2.IsNaN())
  830. throw MathException(Overflow);
  831. return mpfr_cmp_si(num2.number, num1) != 0;
  832. }
  833. /**
  834. * Not equality operator.
  835. * @exception MathException Thrown when the mathematics error condition occurs.
  836. * @param num1 The first instance to compare.
  837. * @param num2 The second instance to compare.
  838. * @return true if the parameters are not considered equivalent.
  839. */
  840. bool operator!=(const Real& num1, const float num2)
  841. {
  842. if (num1.IsNaN())
  843. throw MathException(Overflow);
  844. return mpfr_cmp_d(num1.number, num2) != 0;
  845. }
  846. /**
  847. * Not equality operator.
  848. * @exception MathException Thrown when the mathematics error condition occurs.
  849. * @param num1 The first instance to compare.
  850. * @param num2 The second instance to compare.
  851. * @return true if the parameters are not considered equivalent.
  852. */
  853. bool operator!=(const float num1, const Real& num2)
  854. {
  855. if (num2.IsNaN())
  856. throw MathException(Overflow);
  857. return mpfr_cmp_d(num2.number, num1) != 0;
  858. }
  859. /**
  860. * Greater-than comparison operator.
  861. * @exception MathException Thrown when the mathematics error condition occurs.
  862. * @param num1 The first instance to compare.
  863. * @param num2 The second instance to compare.
  864. * @return true if the first parameter is greater than to the second.
  865. */
  866. bool operator>(const Real& num1, const Real& num2)
  867. {
  868. if (num1.IsNaN() || num2.IsNaN())
  869. throw MathException(Overflow);
  870. return mpfr_greater_p(num1.number, num2.number) != 0;
  871. }
  872. /**
  873. * Greater-than comparison operator.
  874. * @exception MathException Thrown when the mathematics error condition occurs.
  875. * @param num1 The first instance to compare.
  876. * @param num2 The second instance to compare.
  877. * @return true if the first parameter is greater than to the second.
  878. */
  879. bool operator>(const Real& num1, const int num2)
  880. {
  881. if (num1.IsNaN())
  882. throw MathException(Overflow);
  883. return mpfr_cmp_si(num1.number, num2) > 0;
  884. }
  885. /**
  886. * Greater-than comparison operator.
  887. * @param num1 The first instance to compare.
  888. * @param num2 The second instance to compare.
  889. * @return true if the first parameter is greater than to the second.
  890. */
  891. bool operator>(const int num1, const Real& num2)
  892. {
  893. Real _num1(num2.GetBitPrecision(), num1);
  894. return _num1 > num2;
  895. }
  896. /**
  897. * Greater-than comparison operator.
  898. * @exception MathException Thrown when the mathematics error condition occurs.
  899. * @param num1 The first instance to compare.
  900. * @param num2 The second instance to compare.
  901. * @return true if the first parameter is greater than to the second.
  902. */
  903. bool operator>(const Real& num1, const float num2)
  904. {
  905. if (num1.IsNaN())
  906. throw MathException(Overflow);
  907. return mpfr_cmp_d(num1.number, num2) > 0;
  908. }
  909. /**
  910. * Greater-than comparison operator.
  911. * @param num1 The first instance to compare.
  912. * @param num2 The second instance to compare.
  913. * @return true if the first parameter is greater than to the second.
  914. */
  915. bool operator>(const float num1, const Real& num2)
  916. {
  917. Real _num1(num2.GetBitPrecision(), num1);
  918. return _num1 > num2;
  919. }
  920. /**
  921. * Greater-than-or-equal comparison operator.
  922. * @exception MathException Thrown when the mathematics error condition occurs.
  923. * @param num1 The first instance to compare.
  924. * @param num2 The second instance to compare.
  925. * @return true if the first parameter is greater than or equal to the second.
  926. */
  927. bool operator>=(const Real& num1, const Real& num2)
  928. {
  929. if (num1.IsNaN() || num2.IsNaN())
  930. throw MathException(Overflow);
  931. return mpfr_greaterequal_p(num1.number, num2.number) != 0;
  932. }
  933. /**
  934. * Greater-than-or-equal comparison operator.
  935. * @param num1 The first instance to compare.
  936. * @param num2 The second instance to compare.
  937. * @return true if the first parameter is greater than or equal to the second.
  938. */
  939. bool operator>=(const Real& num1, const int num2)
  940. {
  941. return (num1 > num2) || (num1 == num2);
  942. }
  943. /**
  944. * Greater-than-or-equal comparison operator.
  945. * @param num1 The first instance to compare.
  946. * @param num2 The second instance to compare.
  947. * @return true if the first parameter is greater than or equal to the second.
  948. */
  949. bool operator>=(const int num1, const Real& num2)
  950. {
  951. return (num1 > num2) || (num1 == num2);
  952. }
  953. /**
  954. * Greater-than-or-equal comparison operator.
  955. * @param num1 The first instance to compare.
  956. * @param num2 The second instance to compare.
  957. * @return true if the first parameter is greater than or equal to the second.
  958. */
  959. bool operator>=(const Real& num1, const float num2)
  960. {
  961. return (num1 > num2) || (num1 == num2);
  962. }
  963. /**
  964. * Greater-than-or-equal comparison operator.
  965. * @param num1 The first instance to compare.
  966. * @param num2 The second instance to compare.
  967. * @return true if the first parameter is greater than or equal to the second.
  968. */
  969. bool operator>=(const float num1, const Real& num2)
  970. {
  971. return (num1 > num2) || (num1 == num2);
  972. }
  973. /**
  974. * Less-than comparison operator.
  975. * @exception MathException Thrown when the mathematics error condition occurs.
  976. * @param num1 The first instance to compare.
  977. * @param num2 The second instance to compare.
  978. * @return true if the first parameter is less than the second.
  979. */
  980. bool operator<(const Real& num1, const Real& num2)
  981. {
  982. if (num1.IsNaN() || num2.IsNaN())
  983. throw MathException(Overflow);
  984. return mpfr_less_p(num1.number, num2.number) != 0;
  985. }
  986. /**
  987. * Less-than comparison operator.
  988. * @exception MathException Thrown when the mathematics error condition occurs.
  989. * @param num1 The first instance to compare.
  990. * @param num2 The second instance to compare.
  991. * @return true if the first parameter is less than the second.
  992. */
  993. bool operator<(const Real& num1, const int num2)
  994. {
  995. if (num1.IsNaN())
  996. throw MathException(Overflow);
  997. return mpfr_cmp_si(num1.number, num2) < 0;
  998. }
  999. /**
  1000. * Less-than comparison operator.
  1001. * @param num1 The first instance to compare.
  1002. * @param num2 The second instance to compare.
  1003. * @return true if the first parameter is less than the second.
  1004. */
  1005. bool operator<(const int num1, const Real& num2)
  1006. {
  1007. Real _num1(num2.GetBitPrecision(), num1);
  1008. return _num1 < num2;
  1009. }
  1010. /**
  1011. * Less-than comparison operator.
  1012. * @exception MathException Thrown when the mathematics error condition occurs.
  1013. * @param num1 The first instance to compare.
  1014. * @param num2 The second instance to compare.
  1015. * @return true if the first parameter is less than the second.
  1016. */
  1017. bool operator<(const Real& num1, const float num2)
  1018. {
  1019. if (num1.IsNaN())
  1020. throw MathException(Overflow);
  1021. return mpfr_cmp_d(num1.number, num2) < 0;
  1022. }
  1023. /**
  1024. * Less-than comparison operator.
  1025. * @param num1 The first instance to compare.
  1026. * @param num2 The second instance to compare.
  1027. * @return true if the first parameter is less than the second.
  1028. */
  1029. bool operator<(const float num1, const Real& num2)
  1030. {
  1031. Real _num1(num2.GetBitPrecision(), num1);
  1032. return _num1 < num2;
  1033. }
  1034. /**
  1035. * Less-than-or-equal comparison operator.
  1036. * @exception MathException Thrown when the mathematics error condition occurs.
  1037. * @param num1 The first instance to compare.
  1038. * @param num2 The second instance to compare.
  1039. * @return true if the first parameter is less than or equal to the second.
  1040. */
  1041. bool operator<=(const Real& num1, const Real& num2)
  1042. {
  1043. if (num1.IsNaN() || num2.IsNaN())
  1044. throw MathException(Overflow);
  1045. return mpfr_lessequal_p(num1.number, num2.number) != 0;
  1046. }
  1047. /**
  1048. * Less-than-or-equal comparison operator.
  1049. * @param num1 The first instance to compare.
  1050. * @param num2 The second instance to compare.
  1051. * @return true if the first parameter is less than or equal to the second.
  1052. */
  1053. bool operator<=(const Real& num1, const int num2)
  1054. {
  1055. return (num1 < num2) || (num1 == num2);
  1056. }
  1057. /**
  1058. * Less-than-or-equal comparison operator.
  1059. * @param num1 The first instance to compare.
  1060. * @param num2 The second instance to compare.
  1061. * @return true if the first parameter is less than or equal to the second.
  1062. */
  1063. bool operator<=(const int num1, const Real& num2)
  1064. {
  1065. return (num1 < num2) || (num1 == num2);
  1066. }
  1067. /**
  1068. * Less-than-or-equal comparison operator.
  1069. * @param num1 The first instance to compare.
  1070. * @param num2 The second instance to compare.
  1071. * @return true if the first parameter is less than or equal to the second.
  1072. */
  1073. bool operator<=(const Real& num1, const float num2)
  1074. {
  1075. return (num1 < num2) || (num1 == num2);
  1076. }
  1077. /**
  1078. * Less-than-or-equal comparison operator.
  1079. * @param num1 The first instance to compare.
  1080. * @param num2 The second instance to compare.
  1081. * @return true if the first parameter is less than or equal to the second.
  1082. */
  1083. bool operator<=(const float num1, const Real& num2)
  1084. {
  1085. return (num1 < num2) || (num1 == num2);
  1086. }
  1087. /**
  1088. * Exponent function.
  1089. * @exception MathException Thrown when the mathematics error condition occurs.
  1090. * @param num The argument.
  1091. * @return The number raised to the exponent.
  1092. */
  1093. Real exp(const Real& num)
  1094. {
  1095. Real res(num.GetBitPrecision());
  1096. while (mpfr_exp(res.number, num.number, DEFAULT_RND) < 0)
  1097. {
  1098. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1099. throw MathException(Overflow);
  1100. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1101. }
  1102. //mpfr_exp(res.number, num.number, DEFAULT_RND);
  1103. return res;
  1104. }
  1105. /**
  1106. * Natural logarithm function.
  1107. * @exception MathException Thrown when the mathematics error condition occurs.
  1108. * @param num The argument.
  1109. * @return The natural logarithm of the number.
  1110. */
  1111. Real ln(const Real& num)
  1112. {
  1113. Real res(num.GetBitPrecision());
  1114. while (mpfr_log(res.number, num.number, DEFAULT_RND) < 0)
  1115. {
  1116. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1117. throw MathException(Overflow);
  1118. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1119. }
  1120. //mpfr_log(res.number, num.number, DEFAULT_RND);
  1121. return res;
  1122. }
  1123. /**
  1124. * Base 10 logarithm function.
  1125. * @param num The argument.
  1126. * @return Base 10 logarithm of the number.
  1127. */
  1128. Real lg(const Real& num)
  1129. {
  1130. Real res = ln(num) / ln(Real(num.GetBitPrecision(), 10));
  1131. return res;
  1132. }
  1133. /**
  1134. * Logarithm with base function.
  1135. * @param num1 The base.
  1136. * @param num2 The argument.
  1137. * @return Logarithm with base of the number.
  1138. */
  1139. Real log(const Real& num1, const Real& num2)
  1140. {
  1141. Real res = ln(num2) / ln(num1);
  1142. return res;
  1143. }
  1144. /**
  1145. * Sine function.
  1146. * @exception MathException Thrown when the mathematics error condition occurs.
  1147. * @param num The argument.
  1148. * @param angleMeasure The angle measure.
  1149. * @return The sinus of the number.
  1150. */
  1151. Real sin(const Real& num, AngleMeasure angleMeasure)
  1152. {
  1153. Real res(num.GetBitPrecision());
  1154. if (angleMeasure != RADIAN)
  1155. {
  1156. Real _num(num.GetBitPrecision());
  1157. if (angleMeasure == DEGREE)
  1158. _num = num.DegreeToRadian();
  1159. else if (angleMeasure == GRAD)
  1160. _num = num.GradToRadian();
  1161. while (mpfr_sin(res.number, _num.number, DEFAULT_RND) < 0)
  1162. {
  1163. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1164. throw MathException(Overflow);
  1165. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1166. }
  1167. return res;
  1168. }
  1169. Real misc = MathHelper::GetMisc<Real>(num);
  1170. Real _pi = pi(num.GetBitPrecision());
  1171. Real pi2 = pi(num.GetBitPrecision()) * 2;
  1172. Real _num = num;
  1173. Real mul = round(_num / pi2);
  1174. _num -= mul * pi2;
  1175. _num = abs(_num);
  1176. if (_num <= misc)
  1177. {
  1178. res = 0;
  1179. }
  1180. else if (abs(_num - _pi) <= misc)
  1181. {
  1182. res = 0;
  1183. }
  1184. else
  1185. {
  1186. while (mpfr_sin(res.number, num.number, DEFAULT_RND) < 0)
  1187. {
  1188. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1189. throw MathException(Overflow);
  1190. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1191. }
  1192. }
  1193. return res;
  1194. }
  1195. /**
  1196. * Cosine function.
  1197. * @exception MathException Thrown when the mathematics error condition occurs.
  1198. * @param num The argument.
  1199. * @param angleMeasure The angle measure.
  1200. * @return The cosine of the number.
  1201. */
  1202. Real cos(const Real& num, AngleMeasure angleMeasure)
  1203. {
  1204. Real res(num.GetBitPrecision());
  1205. if (angleMeasure != RADIAN)
  1206. {
  1207. Real _num(num.GetBitPrecision());
  1208. if (angleMeasure == DEGREE)
  1209. _num = num.DegreeToRadian();
  1210. else if (angleMeasure == GRAD)
  1211. _num = num.GradToRadian();
  1212. while (mpfr_cos(res.number, _num.number, DEFAULT_RND) < 0)
  1213. {
  1214. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1215. throw MathException(Overflow);
  1216. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1217. }
  1218. return res;
  1219. }
  1220. Real _pi = pi(num.GetBitPrecision());
  1221. Real pi2 = pi(num.GetBitPrecision()) * 2;
  1222. Real mul = round(num / pi2);
  1223. Real _num = num;
  1224. _num -= mul * pi2;
  1225. _num = abs(_num);
  1226. if (_num == 0)
  1227. {
  1228. res = 1;
  1229. }
  1230. else if (_num == _pi)
  1231. {
  1232. res = -1;
  1233. }
  1234. else if (_num == _pi / 2)
  1235. {
  1236. res = 0;
  1237. }
  1238. else if (_num == 3 * _pi / 2)
  1239. {
  1240. res = 0;
  1241. }
  1242. else
  1243. {
  1244. while (mpfr_cos(res.number, num.number, DEFAULT_RND) < 0)
  1245. {
  1246. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1247. throw MathException(Overflow);
  1248. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1249. }
  1250. }
  1251. return res;
  1252. }
  1253. /**
  1254. * Tangent function.
  1255. * @exception MathException Thrown when the mathematics error condition occurs.
  1256. * @param num The argument.
  1257. * @param angleMeasure The angle measure.
  1258. * @return The tangent of the number.
  1259. */
  1260. Real tg(const Real& num, AngleMeasure angleMeasure)
  1261. {
  1262. Real res(num.GetBitPrecision());
  1263. if (angleMeasure != RADIAN)
  1264. {
  1265. Real _num(num.GetBitPrecision());
  1266. if (angleMeasure == DEGREE)
  1267. _num = num.DegreeToRadian();
  1268. else if (angleMeasure == GRAD)
  1269. _num = num.GradToRadian();
  1270. while (mpfr_tan(res.number, _num.number, DEFAULT_RND) < 0)
  1271. {
  1272. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1273. throw MathException(Overflow);
  1274. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1275. }
  1276. return res;
  1277. }
  1278. while (mpfr_tan(res.number, num.number, DEFAULT_RND) < 0)
  1279. {
  1280. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1281. throw MathException(Overflow);
  1282. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1283. }
  1284. if (res.IsInfinity() || res.IsNaN())
  1285. throw MathException(Overflow);
  1286. return res;
  1287. }
  1288. /**
  1289. * Cotangent function.
  1290. * @exception MathException Thrown when the mathematics error condition occurs.
  1291. * @param num The argument.
  1292. * @param angleMeasure The angle measure.
  1293. * @return The cotangent of the number.
  1294. */
  1295. Real ctg(const Real& num, AngleMeasure angleMeasure)
  1296. {
  1297. Real res(num.GetBitPrecision());
  1298. if (angleMeasure != RADIAN)
  1299. {
  1300. Real _num(num.GetBitPrecision());
  1301. if (angleMeasure == DEGREE)
  1302. _num = num.DegreeToRadian();
  1303. else if (angleMeasure == GRAD)
  1304. _num = num.GradToRadian();
  1305. while (mpfr_cot(res.number, _num.number, DEFAULT_RND) < 0)
  1306. {
  1307. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1308. throw MathException(Overflow);
  1309. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1310. }
  1311. return res;
  1312. }
  1313. while (mpfr_cot(res.number, num.number, DEFAULT_RND) < 0)
  1314. {
  1315. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1316. throw MathException(Overflow);
  1317. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1318. }
  1319. if (res.IsInfinity() || res.IsNaN())
  1320. throw MathException(Overflow);
  1321. return res;
  1322. }
  1323. /**
  1324. * Secant function.
  1325. * @exception MathException Thrown when the mathematics error condition occurs.
  1326. * @param num The argument.
  1327. * @param angleMeasure The angle measure.
  1328. * @return The secant of the number.
  1329. */
  1330. Real sec(const Real& num, AngleMeasure angleMeasure)
  1331. {
  1332. Real res(num.GetBitPrecision());
  1333. if (angleMeasure != RADIAN)
  1334. {
  1335. Real _num(num.GetBitPrecision());
  1336. if (angleMeasure == DEGREE)
  1337. _num = num.DegreeToRadian();
  1338. else if (angleMeasure == GRAD)
  1339. _num = num.GradToRadian();
  1340. while (mpfr_sec(res.number, _num.number, DEFAULT_RND) < 0)
  1341. {
  1342. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1343. throw MathException(Overflow);
  1344. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1345. }
  1346. return res;
  1347. }
  1348. while (mpfr_sec(res.number, num.number, DEFAULT_RND) < 0)
  1349. {
  1350. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1351. throw MathException(Overflow);
  1352. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1353. }
  1354. return res;
  1355. }
  1356. /**
  1357. * Cosecant function.
  1358. * @exception MathException Thrown when the mathematics error condition occurs.
  1359. * @param num The argument.
  1360. * @param angleMeasure The angle measure.
  1361. * @return The cosecant of the number.
  1362. */
  1363. Real cosec(const Real& num, AngleMeasure angleMeasure)
  1364. {
  1365. Real res(num.GetBitPrecision());
  1366. if (angleMeasure != RADIAN)
  1367. {
  1368. Real _num(num.GetBitPrecision());
  1369. if (angleMeasure == DEGREE)
  1370. _num = num.DegreeToRadian();
  1371. else if (angleMeasure == GRAD)
  1372. _num = num.GradToRadian();
  1373. while (mpfr_csc(res.number, _num.number, DEFAULT_RND) < 0)
  1374. {
  1375. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1376. throw MathException(Overflow);
  1377. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1378. }
  1379. return res;
  1380. }
  1381. while (mpfr_csc(res.number, num.number, DEFAULT_RND) < 0)
  1382. {
  1383. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1384. throw MathException(Overflow);
  1385. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1386. }
  1387. return res;
  1388. }
  1389. /**
  1390. * Arcsine function.
  1391. * @exception MathException Thrown when the mathematics error condition occurs.
  1392. * @param num The argument.
  1393. * @param angleMeasure The angle measure.
  1394. * @return The arcsine of the number.
  1395. */
  1396. Real arcsin(const Real& num, AngleMeasure angleMeasure)
  1397. {
  1398. Real res(num.GetBitPrecision());
  1399. if (abs(num) > 1)
  1400. throw MathException(Overflow);
  1401. while (mpfr_asin(res.number, num.number, DEFAULT_RND) < 0)
  1402. {
  1403. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1404. throw MathException(Overflow);
  1405. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1406. }
  1407. if (angleMeasure == DEGREE)
  1408. res = res.RadianToDegree();
  1409. else if (angleMeasure == GRAD)
  1410. res = res.RadianToGrad();
  1411. return res;
  1412. }
  1413. /**
  1414. * Arccosine function.
  1415. * @exception MathException Thrown when the mathematics error condition occurs.
  1416. * @param num The argument.
  1417. * @param angleMeasure The angle measure.
  1418. * @return The arccosine of the number.
  1419. */
  1420. Real arccos(const Real& num, AngleMeasure angleMeasure)
  1421. {
  1422. Real res(num.GetBitPrecision());
  1423. if (abs(num) > 1)
  1424. throw MathException(Overflow);
  1425. while (mpfr_acos(res.number, num.number, DEFAULT_RND) < 0)
  1426. {
  1427. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1428. throw MathException(Overflow);
  1429. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1430. }
  1431. if (angleMeasure == DEGREE)
  1432. res = res.RadianToDegree();
  1433. else if (angleMeasure == GRAD)
  1434. res = res.RadianToGrad();
  1435. return res;
  1436. }
  1437. /**
  1438. * Arctangent function.
  1439. * @exception MathException Thrown when the mathematics error condition occurs.
  1440. * @param num The argument.
  1441. * @param angleMeasure The angle measure.
  1442. * @return The arctangent of the number.
  1443. */
  1444. Real arctg(const Real& num, AngleMeasure angleMeasure)
  1445. {
  1446. Real res(num.GetBitPrecision());
  1447. while (mpfr_atan(res.number, num.number, DEFAULT_RND) < 0)
  1448. {
  1449. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1450. throw MathException(Overflow);
  1451. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1452. }
  1453. if (angleMeasure == DEGREE)
  1454. res = res.RadianToDegree();
  1455. else if (angleMeasure == GRAD)
  1456. res = res.RadianToGrad();
  1457. return res;
  1458. }
  1459. /**
  1460. * Arccotangent function.
  1461. * @exception MathException Thrown when the mathematics error condition occurs.
  1462. * @param num The argument.
  1463. * @param angleMeasure The angle measure.
  1464. * @return The arccotangent of the number.
  1465. */
  1466. Real arcctg(const Real& num, AngleMeasure angleMeasure)
  1467. {
  1468. Real _pi = pi(num.GetBitPrecision());
  1469. if (angleMeasure == DEGREE)
  1470. _pi = _pi.RadianToDegree();
  1471. else if (angleMeasure == GRAD)
  1472. _pi = _pi.RadianToGrad();
  1473. Real res(_pi / 2 - arctg(num, angleMeasure));
  1474. return res;
  1475. }
  1476. /**
  1477. * Arcsecant function.
  1478. * @exception MathException Thrown when the mathematics error condition occurs.
  1479. * @param num The argument.
  1480. * @param angleMeasure The angle measure.
  1481. * @return The arcsecant of the number.
  1482. */
  1483. Real arcsec(const Real& num, AngleMeasure angleMeasure)
  1484. {
  1485. Real res(arccos(1 / num, angleMeasure));
  1486. return res;
  1487. }
  1488. /**
  1489. * Acrcosecant function.
  1490. * @exception MathException Thrown when the mathematics error condition occurs.
  1491. * @param num The argument.
  1492. * @param angleMeasure The angle measure.
  1493. * @return The arccosecant of the number.
  1494. */
  1495. Real arccosec(const Real& num, AngleMeasure angleMeasure)
  1496. {
  1497. Real res(arcsin(1 / num, angleMeasure));
  1498. return res;
  1499. }
  1500. /**
  1501. * Hyperbolic sine function.
  1502. * @exception MathException Thrown when the mathematics error condition occurs.
  1503. * @param num The argument.
  1504. * @param angleMeasure The angle measure.
  1505. * @return The hyperbolic sine of the number.
  1506. */
  1507. Real sh(const Real& num, AngleMeasure angleMeasure)
  1508. {
  1509. Real res(num.GetBitPrecision());
  1510. if (angleMeasure != RADIAN)
  1511. {
  1512. Real _num(num.GetBitPrecision());
  1513. if (angleMeasure == DEGREE)
  1514. _num = num.DegreeToRadian();
  1515. else if (angleMeasure == GRAD)
  1516. _num = num.GradToRadian();
  1517. while (mpfr_sinh(res.number, _num.number, DEFAULT_RND) < 0)
  1518. {
  1519. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1520. throw MathException(Overflow);
  1521. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1522. }
  1523. //mpfr_sinh(res.number, _num.number, DEFAULT_RND);
  1524. return res;
  1525. }
  1526. while (mpfr_sinh(res.number, num.number, DEFAULT_RND) < 0)
  1527. {
  1528. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1529. throw MathException(Overflow);
  1530. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1531. }
  1532. //mpfr_sinh(res.number, num.number, DEFAULT_RND);
  1533. if (res.IsInfinity() || res.IsNaN())
  1534. throw MathException(Overflow);
  1535. return res;
  1536. }
  1537. /**
  1538. * Hyperbolic cosine function.
  1539. * @exception MathException Thrown when the mathematics error condition occurs.
  1540. * @param num The argument.
  1541. * @param angleMeasure The angle measure.
  1542. * @return The hyperbolic cosine of the number.
  1543. */
  1544. Real ch(const Real& num, AngleMeasure angleMeasure)
  1545. {
  1546. Real res(num.GetBitPrecision());
  1547. if (angleMeasure != RADIAN)
  1548. {
  1549. Real _num(num.GetBitPrecision());
  1550. if (angleMeasure == DEGREE)
  1551. _num = num.DegreeToRadian();
  1552. else if (angleMeasure == GRAD)
  1553. _num = num.GradToRadian();
  1554. while (mpfr_cosh(res.number, _num.number, DEFAULT_RND) < 0)
  1555. {
  1556. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1557. throw MathException(Overflow);
  1558. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1559. }
  1560. //mpfr_cosh(res.number, _num.number, DEFAULT_RND);
  1561. return res;
  1562. }
  1563. while (mpfr_cosh(res.number, num.number, DEFAULT_RND) < 0)
  1564. {
  1565. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1566. throw MathException(Overflow);
  1567. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1568. }
  1569. //mpfr_cosh(res.number, num.number, DEFAULT_RND);
  1570. if (res.IsInfinity() || res.IsNaN())
  1571. throw MathException(Overflow);
  1572. return res;
  1573. }
  1574. /**
  1575. * Hyperbolic tangent function.
  1576. * @exception MathException Thrown when the mathematics error condition occurs.
  1577. * @param num The argument.
  1578. * @param angleMeasure The angle measure.
  1579. * @return The hyperbolic tangent of the number.
  1580. */
  1581. Real th(const Real& num, AngleMeasure angleMeasure)
  1582. {
  1583. Real res(num.GetBitPrecision());
  1584. if (angleMeasure != RADIAN)
  1585. {
  1586. Real _num(num.GetBitPrecision());
  1587. if (angleMeasure == DEGREE)
  1588. _num = num.DegreeToRadian();
  1589. else if (angleMeasure == GRAD)
  1590. _num = num.GradToRadian();
  1591. while (mpfr_tanh(res.number, _num.number, DEFAULT_RND) < 0)
  1592. {
  1593. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1594. throw MathException(Overflow);
  1595. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1596. }
  1597. //mpfr_tanh(res.number, _num.number, DEFAULT_RND);
  1598. return res;
  1599. }
  1600. while (mpfr_tanh(res.number, num.number, DEFAULT_RND) < 0)
  1601. {
  1602. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1603. throw MathException(Overflow);
  1604. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1605. }
  1606. if (res.IsInfinity() || res.IsNaN())
  1607. throw MathException(Overflow);
  1608. //mpfr_tanh(res.number, num.number, DEFAULT_RND);
  1609. return res;
  1610. }
  1611. /**
  1612. * Hyperbolic cotangent function.
  1613. * @exception MathException Thrown when the mathematics error condition occurs.
  1614. * @param num The argument.
  1615. * @param angleMeasure The angle measure.
  1616. * @return The hyperbolic cotangent of the number.
  1617. */
  1618. Real cth(const Real& num, AngleMeasure angleMeasure)
  1619. {
  1620. Real res(num.GetBitPrecision());
  1621. if (angleMeasure != RADIAN)
  1622. {
  1623. Real _num(num.GetBitPrecision());
  1624. if (angleMeasure == DEGREE)
  1625. _num = num.DegreeToRadian();
  1626. else if (angleMeasure == GRAD)
  1627. _num = num.GradToRadian();
  1628. while (mpfr_coth(res.number, _num.number, DEFAULT_RND) < 0)
  1629. {
  1630. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1631. throw MathException(Overflow);
  1632. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1633. }
  1634. //mpfr_coth(res.number, _num.number, DEFAULT_RND);
  1635. return res;
  1636. }
  1637. while (mpfr_coth(res.number, num.number, DEFAULT_RND) < 0)
  1638. {
  1639. if (res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION >= MPFR_PREC_MAX)
  1640. throw MathException(Overflow);
  1641. res.SetBitPrecision(res.GetBitPrecision() + DEFAULT_INCREASE_PRECISION);
  1642. }
  1643. if (res.IsInfinity() || res.IsNaN())
  1644. throw MathException(Overflow);
  1645. //mpfr_coth(res.number, num.number, DEFAULT_RND);
  1646. return res;
  1647. }
  1648. /**
  1649. * Hyperbolic secant function.
  1650. * @exception MathException Thrown when the mathematics error condition occurs.
  1651. * @param num The argument.
  1652. * @param angleMeasure The angle measure.
  1653. * @return The hyperbolic secant of the number.
  1654. */
  1655. Real sch(const Real& num, AngleMeasure angleMeasure)
  1656. {
  1657. Real res(num.GetBitPrecision());
  1658. if (angleMeasure != RADIAN)
  1659. {
  1660. Real _num(num.GetBitPrecision());
  1661. if (angleMeasure == DEGREE)
  1662. _num = num.DegreeToRadian();
  1663. else if (angleMeasure == GRAD)
  1664. _num = num.GradToRadian();
  1665. mpfr_sech(res.number, _num.number, DEFAULT_RND);
  1666. return res;
  1667. }
  1668. mpfr_sech(res.number, num.number, DEFAULT_RND);
  1669. return res;
  1670. }
  1671. /**
  1672. * Hyperbolic cosecant function.
  1673. * @exception MathException Thrown when the mathematics error condition occurs.
  1674. * @param num The argument.
  1675. * @param angleMeasure The angle measure.
  1676. * @return The hyperbolic cosecant of the number.
  1677. */
  1678. Real csch(const Real& num, AngleMeasure angleMeasure)
  1679. {
  1680. Real res(num.GetBitPrecision());
  1681. if (angleMeasure != RADIAN)
  1682. {
  1683. Real _num(num.GetBitPrecision());
  1684. if (angleMeasure == DEGREE)
  1685. _num = num.DegreeToRadian();
  1686. else if (angleMeasure == GRAD)
  1687. _num = num.GradToRadian();
  1688. mpfr_csch(res.number, _num.number, DEFAULT_RND);
  1689. return res;
  1690. }
  1691. mpfr_csch(res