/src/lib/numeric/number.e

http://github.com/tybor/Liberty · Specman e · 1062 lines · 832 code · 107 blank · 123 comment · 17 complexity · 8af2d76fedaae0ba076f8897b9049957 MD5 · raw file

  1. -- This file is part of a Liberty Eiffel library.
  2. -- See the full copyright at the end.
  3. --
  4. deferred class NUMBER
  5. --
  6. -- This abstract definition of a NUMBER is intended to be the unique
  7. -- view of the client (do not use sub-classes names at all in the
  8. -- client code). In order to create NUMBERs without using concrete
  9. -- class name, the client code can inherit NUMBER_TOOLS. (See directory
  10. -- tutorial/number for examples.)
  11. --
  12. inherit
  13. HASHABLE
  14. redefine fill_tagged_out_memory, out_in_tagged_out_memory
  15. end
  16. COMPARABLE
  17. undefine is_equal
  18. redefine infix ">", infix "<=", infix ">=", in_range, compare, three_way_comparison, min, max, fill_tagged_out_memory,
  19. out_in_tagged_out_memory
  20. end
  21. NUMERIC
  22. redefine fill_tagged_out_memory, out_in_tagged_out_memory
  23. end
  24. insert
  25. PLATFORM
  26. undefine is_equal
  27. redefine fill_tagged_out_memory, out_in_tagged_out_memory
  28. end
  29. feature {ANY} -- Binary operators for two NUMBERs:
  30. infix "+" (other: NUMBER): NUMBER
  31. -- Sum of `Current' and `other'.
  32. require
  33. other /= Void
  34. deferred
  35. ensure
  36. (Result - other).is_equal(Current)
  37. end
  38. infix "-" (other: NUMBER): NUMBER
  39. -- Difference of `Current' and `other'.
  40. require
  41. other /= Void
  42. do
  43. Result := Current + -other
  44. ensure
  45. (Result + other).is_equal(Current)
  46. end
  47. infix "*" (other: NUMBER): NUMBER
  48. -- Product of `Current' and `other'.
  49. require
  50. other /= Void
  51. deferred
  52. ensure
  53. Result /= Void
  54. end
  55. infix "/" (other: NUMBER): NUMBER
  56. -- Quotient of `Current' and `other'.
  57. do
  58. Result := Current * other.inverse
  59. ensure
  60. Result /= Void
  61. end
  62. infix "//" (other: NUMBER): NUMBER
  63. -- Divide `Current' by `other' (Integer division).
  64. require
  65. is_integer_general_number
  66. other.is_integer_general_number
  67. divisible(other)
  68. deferred
  69. ensure
  70. Result.is_integer_general_number
  71. Current.is_equal(Result * other + Current \\ other)
  72. end
  73. infix "\\" (other: NUMBER): NUMBER
  74. -- Remainder of division of `Current' by `other'.
  75. require
  76. is_integer_general_number
  77. other.is_integer_general_number
  78. divisible(other)
  79. deferred
  80. ensure
  81. Result.is_integer_general_number
  82. not Result.is_negative and Result < other.abs
  83. end
  84. infix "^" (exp: NUMBER): NUMBER
  85. -- `Current' raised to `exp'-th power.
  86. require
  87. exp.is_integer_general_number
  88. is_zero implies exp @> 0
  89. local
  90. e: NUMBER; factor: NUMBER
  91. do
  92. Result := one
  93. factor := Current
  94. from
  95. e := exp.abs
  96. until
  97. e.is_zero
  98. loop
  99. if e.is_odd then
  100. Result := Result * factor
  101. end
  102. e := e @// 2
  103. factor := factor * factor
  104. end
  105. if exp @< 0 then
  106. Result := Result.inverse
  107. end
  108. ensure
  109. Result /= Void
  110. exp.is_zero implies Result.is_one
  111. end
  112. infix "<" (other: NUMBER): BOOLEAN
  113. -- Is `Current' strictly less than `other'?
  114. deferred
  115. end
  116. infix "<=" (other: NUMBER): BOOLEAN
  117. -- Is `Current' less or equal than `other'?
  118. do
  119. Result := not (other < Current)
  120. end
  121. infix ">" (other: NUMBER): BOOLEAN
  122. -- Is `Current' strictly greater than `other'?
  123. do
  124. Result := other < Current
  125. end
  126. infix ">=" (other: NUMBER): BOOLEAN
  127. -- Is `Current' greater or equal than `other'?
  128. do
  129. Result := not (Current < other)
  130. end
  131. gcd (other: NUMBER): INTEGER_GENERAL_NUMBER
  132. -- Great Common Divisor of `Current' and `other'.
  133. require
  134. other.is_integer_general_number
  135. is_integer_general_number
  136. deferred
  137. ensure
  138. not Result.is_negative
  139. Result.is_zero implies Current.is_zero and other.is_zero
  140. not Result.is_zero implies (Current / Result).gcd(other / Result).is_one
  141. end
  142. feature {ANY} -- Unary operators for two NUMBERs:
  143. frozen prefix "+": NUMBER
  144. -- Unary plus of `Current'.
  145. do
  146. Result := Current
  147. ensure
  148. Result = Current
  149. end
  150. prefix "-": NUMBER
  151. -- Opposite of `Current'.
  152. deferred
  153. ensure
  154. Result /= Void
  155. end
  156. feature {ANY} -- To know more about a NUMBER:
  157. frozen is_integer_8: BOOLEAN
  158. -- Does `Current' value fit on an INTEGER_8?
  159. local
  160. integer_64_number: INTEGER_64_NUMBER
  161. do
  162. if integer_64_number ?:= Current then
  163. integer_64_number ::= Current
  164. Result := integer_64_number.value.fit_integer_8
  165. end
  166. ensure
  167. Result implies is_integer_general_number
  168. end
  169. frozen is_integer_16: BOOLEAN
  170. -- Does `Current' value fit on an INTEGER_16?
  171. local
  172. integer_64_number: INTEGER_64_NUMBER
  173. do
  174. if integer_64_number ?:= Current then
  175. integer_64_number ::= Current
  176. Result := integer_64_number.value.fit_integer_16
  177. end
  178. ensure
  179. Result implies is_integer_general_number
  180. end
  181. frozen is_integer_32: BOOLEAN
  182. -- Does `Current' value fit on an INTEGER?
  183. local
  184. integer_64_number: INTEGER_64_NUMBER
  185. do
  186. if integer_64_number ?:= Current then
  187. integer_64_number ::= Current
  188. Result := integer_64_number.value.fit_integer_32
  189. end
  190. ensure
  191. Result implies is_integer_general_number
  192. end
  193. frozen is_integer_64: BOOLEAN
  194. -- Does `Current' value fit on an INTEGER_64?
  195. local
  196. integer_64_number: INTEGER_64_NUMBER
  197. do
  198. Result := integer_64_number ?:= Current
  199. ensure
  200. Result implies is_integer_general_number
  201. end
  202. frozen is_natural_64: BOOLEAN
  203. -- Does `Current' value fit on a NATURAL_64?
  204. local
  205. big_integer_number: BIG_INTEGER_NUMBER
  206. do
  207. if is_negative then
  208. check
  209. not Result
  210. end
  211. elseif is_integer_64 then
  212. Result := True
  213. else
  214. big_integer_number ::= Current
  215. Result := big_integer_number.is_natural_64_
  216. end
  217. ensure
  218. Result implies is_integer_general_number
  219. end
  220. in_range (lower, upper: NUMBER): BOOLEAN
  221. -- Return True if `Current' is in range [`lower'..`upper']
  222. do
  223. Result := Current >= lower and then Current <= upper
  224. end
  225. compare, three_way_comparison (other: NUMBER): INTEGER
  226. -- Compare `Current' with `other'.
  227. -- `<' <==> `Result < 0'
  228. -- `>' <==> `Result > 0'
  229. -- Otherwise `Result = 0'.
  230. do
  231. if Current < other then
  232. Result := -1
  233. elseif other < Current then
  234. Result := 1
  235. end
  236. end
  237. min (other: NUMBER): NUMBER
  238. -- Minimum of `Current' and `other'.
  239. do
  240. if Current < other then
  241. Result := Current
  242. else
  243. Result := other
  244. end
  245. end
  246. max (other: NUMBER): NUMBER
  247. -- Maximum of `Current' and `other'.
  248. do
  249. if other < Current then
  250. Result := Current
  251. else
  252. Result := other
  253. end
  254. end
  255. is_zero: BOOLEAN
  256. -- Is it 0 ?
  257. deferred
  258. ensure
  259. Result = Current @= 0
  260. end
  261. is_one: BOOLEAN
  262. -- Is it 1 ?
  263. deferred
  264. ensure
  265. Result = Current @= 1
  266. end
  267. is_positive: BOOLEAN
  268. -- Is `Current' > 0 ?
  269. deferred
  270. ensure
  271. Result = Current @> 0
  272. end
  273. is_negative: BOOLEAN
  274. -- Is `Current' < 0 ?
  275. deferred
  276. ensure
  277. Result = Current @< 0
  278. end
  279. is_odd: BOOLEAN
  280. -- Is `odd' ?
  281. require
  282. is_integer_general_number
  283. do
  284. Result := (Current @\\ 2).is_one
  285. end
  286. is_even: BOOLEAN
  287. -- Is `even' ?
  288. require
  289. is_integer_general_number
  290. do
  291. Result := (Current @\\ 2).is_zero
  292. end
  293. is_equal (other: NUMBER): BOOLEAN
  294. deferred
  295. end
  296. frozen is_integer_general_number: BOOLEAN
  297. local
  298. integer_general_number: INTEGER_GENERAL_NUMBER
  299. do
  300. Result := integer_general_number ?:= Current
  301. end
  302. frozen is_fraction_general_number: BOOLEAN
  303. local
  304. fraction_general_number: FRACTION_GENERAL_NUMBER
  305. do
  306. Result := fraction_general_number ?:= Current
  307. end
  308. frozen fit_real: BOOLEAN
  309. do
  310. if Current #>= Minimum_real then
  311. Result := Current #<= Maximum_real
  312. end
  313. end
  314. feature {ANY} -- Conversions and printing:
  315. frozen to_integer_8: INTEGER_8
  316. -- Conversion of `Current' in an INTEGER_8.
  317. require
  318. is_integer_8
  319. local
  320. integer_64_number: INTEGER_64_NUMBER
  321. do
  322. integer_64_number ::= Current
  323. Result := integer_64_number.value.to_integer_8
  324. end
  325. frozen to_integer_16: INTEGER_16
  326. -- Conversion of `Current' in an INTEGER_16.
  327. require
  328. is_integer_16
  329. local
  330. integer_64_number: INTEGER_64_NUMBER
  331. do
  332. integer_64_number ::= Current
  333. Result := integer_64_number.value.to_integer_16
  334. end
  335. frozen to_integer_32: INTEGER
  336. -- Conversion of `Current' in an INTEGER_32.
  337. require
  338. is_integer_32
  339. local
  340. integer_64_number: INTEGER_64_NUMBER
  341. do
  342. integer_64_number ::= Current
  343. Result := integer_64_number.value.to_integer_32
  344. end
  345. frozen to_integer_64: INTEGER_64
  346. -- Conversion of `Current' in an INTEGER.
  347. require
  348. is_integer_64
  349. local
  350. integer_64_number: INTEGER_64_NUMBER
  351. do
  352. integer_64_number ::= Current
  353. Result := integer_64_number.value
  354. end
  355. frozen to_natural_64: NATURAL_64
  356. -- Conversion of `Current' in a NATURAL_64.
  357. require
  358. is_natural_64
  359. local
  360. integer_64_number: INTEGER_64_NUMBER; big_integer_number: BIG_INTEGER_NUMBER
  361. do
  362. if {INTEGER_64_NUMBER} ?:= Current then
  363. integer_64_number ::= Current
  364. Result := integer_64_number.value.to_natural_64
  365. else
  366. big_integer_number ::= Current
  367. Result := big_integer_number.to_natural_64_
  368. end
  369. end
  370. force_to_real_64: REAL_64
  371. -- Conversion of `Current' in a REAL_64.
  372. require
  373. fit_real
  374. deferred
  375. end
  376. frozen to_string: STRING
  377. -- Convert the NUMBER into a new allocated STRING.
  378. -- Note: see also `append_in' to save memory.
  379. do
  380. string_buffer.clear_count
  381. append_in(string_buffer)
  382. Result := string_buffer.twin
  383. end
  384. frozen to_unicode_string: UNICODE_STRING
  385. -- Convert the NUMBER into a new allocated UNICODE_STRING.
  386. -- Note: see also `append_in_unicode' to save memory.
  387. do
  388. unicode_string_buffer.clear_count
  389. append_in_unicode(unicode_string_buffer)
  390. Result := unicode_string_buffer.twin
  391. end
  392. append_in (buffer: STRING)
  393. -- Append the equivalent of `to_string' at the end of `buffer'.
  394. -- Thus you can save memory because no other STRING is allocated
  395. -- for the job.
  396. require
  397. buffer /= Void
  398. deferred
  399. end
  400. append_in_unicode (buffer: UNICODE_STRING)
  401. -- Append the equivalent of `to_unicode_string' at the end of `buffer'.
  402. -- Thus you can save memory because no other UNICODE_STRING is allocated
  403. -- for the job.
  404. require
  405. buffer /= Void
  406. deferred
  407. end
  408. frozen to_string_format (s: INTEGER): STRING
  409. -- Same as `to_string' but the result is on `s' character and the
  410. -- number is right aligned.
  411. -- Note: see `append_in_format' to save memory.
  412. require
  413. to_string.count <= s
  414. local
  415. i: INTEGER
  416. do
  417. string_buffer.clear_count
  418. append_in(string_buffer)
  419. from
  420. create Result.make(string_buffer.count.max(s))
  421. i := s - string_buffer.count
  422. until
  423. i <= 0
  424. loop
  425. Result.extend(' ')
  426. i := i - 1
  427. end
  428. Result.append(string_buffer)
  429. ensure
  430. Result.count = s
  431. end
  432. frozen to_unicode_string_format (s: INTEGER): UNICODE_STRING
  433. -- Same as `to_unicode_string' but the result is on `s' character and
  434. -- the number is right aligned.
  435. -- Note: see `append_in_unicode_format' to save memory.
  436. require
  437. to_string.count <= s
  438. local
  439. i: INTEGER
  440. do
  441. unicode_string_buffer.clear_count
  442. append_in_unicode(unicode_string_buffer)
  443. from
  444. create Result.make(unicode_string_buffer.count.max(s))
  445. i := s - unicode_string_buffer.count
  446. until
  447. i <= 0
  448. loop
  449. Result.extend(' '.code)
  450. i := i - 1
  451. end
  452. Result.append(unicode_string_buffer)
  453. ensure
  454. Result.count = s
  455. end
  456. frozen append_in_format (str: STRING; s: INTEGER)
  457. -- Append the equivalent of `to_string_format' at the end of
  458. -- `str'. Thus you can save memory because no other
  459. -- STRING is allocated for the job.
  460. require
  461. to_string.count <= s
  462. local
  463. i: INTEGER
  464. do
  465. string_buffer.clear_count
  466. append_in(string_buffer)
  467. from
  468. i := s - string_buffer.count
  469. until
  470. i <= 0
  471. loop
  472. str.extend(' ')
  473. i := i - 1
  474. end
  475. str.append(string_buffer)
  476. ensure
  477. str.count >= old str.count + s
  478. end
  479. frozen append_in_unicode_format (str: UNICODE_STRING; s: INTEGER)
  480. -- Append the equivalent of `to_unicode_string_format' at the end of
  481. -- `str'. Thus you can save memory because no other
  482. -- UNICODE_STRING is allocated for the job.
  483. require
  484. to_string.count <= s
  485. local
  486. i: INTEGER
  487. do
  488. unicode_string_buffer.clear_count
  489. append_in_unicode(unicode_string_buffer)
  490. from
  491. i := s - unicode_string_buffer.count
  492. until
  493. i <= 0
  494. loop
  495. str.extend(' '.code)
  496. i := i - 1
  497. end
  498. str.append(unicode_string_buffer)
  499. ensure
  500. str.count >= old str.count + s
  501. end
  502. frozen to_decimal (digits: INTEGER; all_digits: BOOLEAN): STRING
  503. -- Convert `Current' into its decimal view. A maximum of decimal
  504. -- `digits' places will be used for the decimal part. If the
  505. -- `all_digits' flag is True insignificant digits will be included
  506. -- as well. (See also `decimal_in' to save memory.)
  507. require
  508. non_negative_digits: digits >= 0
  509. do
  510. Result := once "This is a local STRING buffer ...."
  511. Result.clear_count
  512. append_decimal_in(Result, digits, all_digits)
  513. Result := Result.twin
  514. ensure
  515. not Result.is_empty
  516. end
  517. append_decimal_in (buffer: STRING; digits: INTEGER; all_digits: BOOLEAN)
  518. -- Append the equivalent of `to_decimal' at the end of `buffer'. Thus
  519. -- you can save memory because no other STRING is allocated.
  520. require
  521. non_negative_digits: digits >= 0
  522. deferred
  523. end
  524. frozen decimal_digit, digit: CHARACTER
  525. -- Gives the corresponding CHARACTER for range 0..9.
  526. require
  527. to_integer_32.in_range(0, 9)
  528. do
  529. Result := to_integer_32.decimal_digit
  530. ensure
  531. (once "0123456789").has(Result)
  532. Current @= Result.value
  533. end
  534. feature {ANY} -- To mimic NUMERIC:
  535. divisible (other: NUMBER): BOOLEAN
  536. -- Is `other' a valid divisor for `Current' ?
  537. do
  538. Result := not other.is_zero
  539. end
  540. one: NUMBER
  541. -- The neutral element of multiplication.
  542. once
  543. create {INTEGER_64_NUMBER} Result.make(1)
  544. ensure
  545. neutral_element:
  546. -- Result is the neutral element of
  547. -- multiplication.
  548. end
  549. zero: NUMBER
  550. -- The neutral element of addition.
  551. once
  552. create {INTEGER_64_NUMBER} Result.make(0)
  553. ensure
  554. neutral_element:
  555. -- Result is the neutral element of
  556. -- addition.
  557. end
  558. frozen sign: INTEGER_8
  559. -- Sign of `Current' (0 or -1 or 1).
  560. do
  561. if is_positive then
  562. Result := 1
  563. elseif is_negative then
  564. Result := -1
  565. end
  566. ensure then
  567. Result = 1 implies is_positive
  568. Result = 0 implies is_zero
  569. Result = -1 implies is_negative
  570. end
  571. sqrt: REAL_64
  572. -- Compute the square routine.
  573. require
  574. fit_real
  575. do
  576. Result := force_to_real_64.sqrt
  577. end
  578. frozen log: REAL_64
  579. require
  580. fit_real
  581. do
  582. Result := force_to_real_64.log
  583. end
  584. abs: NUMBER
  585. do
  586. if is_negative then
  587. Result := -Current
  588. else
  589. Result := Current
  590. end
  591. ensure
  592. not Result.is_negative
  593. end
  594. feature {ANY} -- To mix NUMBER and INTEGER_64:
  595. infix "@+" (other: INTEGER_64): NUMBER
  596. -- Sum of `Current' and `other'.
  597. deferred
  598. ensure
  599. Result /= Void
  600. end
  601. infix "@-" (other: INTEGER_64): NUMBER
  602. -- Difference of `Current' and `other'.
  603. do
  604. if other = Minimum_integer_64 then
  605. Result := Current @+ 1
  606. Result := Result @+ Maximum_integer_64
  607. else
  608. Result := Current @+ -other
  609. end
  610. ensure
  611. Result /= Void
  612. end
  613. infix "@*" (other: INTEGER_64): NUMBER
  614. deferred
  615. ensure
  616. Result /= Void
  617. end
  618. infix "@/" (other: INTEGER_64): NUMBER
  619. -- Quotient of `Current' and `other'.
  620. require
  621. other /= 0
  622. deferred
  623. ensure
  624. Result /= Void
  625. end
  626. infix "@//" (other: INTEGER_64): NUMBER
  627. -- Divide `Current' by `other' (Integer division).
  628. require
  629. is_integer_general_number
  630. other /= 0
  631. deferred
  632. ensure
  633. Result.is_integer_general_number
  634. end
  635. infix "@\\" (other: INTEGER_64): NUMBER
  636. -- Remainder of division of `Current' by `other'.
  637. require
  638. is_integer_general_number
  639. other /= 0
  640. deferred
  641. ensure
  642. Result.is_integer_general_number
  643. end
  644. infix "@^" (exp: INTEGER_64): NUMBER
  645. require
  646. is_zero implies exp > 0
  647. local
  648. int: INTEGER_64; other: NUMBER
  649. do
  650. int := exp.abs
  651. inspect
  652. int
  653. when 0 then
  654. create {INTEGER_64_NUMBER} Result.make(1)
  655. when 1 then
  656. Result := Current
  657. else
  658. from
  659. int := int - 1
  660. other := Current
  661. Result := Current
  662. until
  663. int < 2
  664. loop
  665. if int.is_odd then
  666. Result := Result * other
  667. end
  668. other := other * other -- method sqrt : ^2
  669. int := int #// 2
  670. end
  671. Result := Result * other
  672. end
  673. if exp < 0 then
  674. Result := Result.inverse
  675. end
  676. ensure
  677. Result /= Void
  678. --|*** Bad assertion (Vincent Croizier, 01/06/04) ***
  679. --| Result /= Current implies (exp /= 1 or else not is_zero)
  680. end
  681. infix "@=" (other: INTEGER_64): BOOLEAN
  682. -- Is `Current' equal `other' ?
  683. deferred
  684. end
  685. infix "@<" (other: INTEGER_64): BOOLEAN
  686. -- Is `Current' strictly less than `other'?
  687. deferred
  688. ensure
  689. Result = not (Current @>= other)
  690. end
  691. infix "@<=" (other: INTEGER_64): BOOLEAN
  692. -- Is `Current' less or equal `other'?
  693. deferred
  694. ensure
  695. Result = not (Current @> other)
  696. end
  697. infix "@>" (other: INTEGER_64): BOOLEAN
  698. -- Is `Current' strictly greater than `other'?
  699. deferred
  700. ensure
  701. Result = not (Current @<= other)
  702. end
  703. infix "@>=" (other: INTEGER_64): BOOLEAN
  704. -- Is `Current' greater or equal than `other'?
  705. deferred
  706. ensure
  707. Result = not (Current @< other)
  708. end
  709. feature {ANY} -- To mix NUMBER and REAL_64:
  710. infix "#=" (other: REAL_64): BOOLEAN
  711. -- Is `Current' equal `other'?
  712. deferred
  713. end
  714. infix "#<" (other: REAL_64): BOOLEAN
  715. -- Is `Current' strictly less than `other'?
  716. deferred
  717. ensure
  718. Result implies not (Current #>= other)
  719. end
  720. infix "#<=" (other: REAL_64): BOOLEAN
  721. -- Is `Current' less or equal `other'?
  722. deferred
  723. ensure
  724. Result = not (Current #> other)
  725. end
  726. infix "#>" (other: REAL_64): BOOLEAN
  727. -- Is `Current' strictly greater than `other'?
  728. deferred
  729. ensure
  730. Result = not (Current #<= other)
  731. end
  732. infix "#>=" (other: REAL_64): BOOLEAN
  733. -- Is `Current' greater or equal than `other'?
  734. deferred
  735. ensure
  736. Result = not (Current #< other)
  737. end
  738. feature {ANY} -- Misc:
  739. out_in_tagged_out_memory, fill_tagged_out_memory
  740. do
  741. append_in(tagged_out_memory)
  742. end
  743. hash_code: INTEGER
  744. deferred
  745. end
  746. inverse: NUMBER
  747. require
  748. divisible(Current)
  749. deferred
  750. ensure
  751. Result /= Void
  752. end
  753. factorial: NUMBER
  754. require
  755. is_integer_general_number
  756. not is_negative
  757. deferred
  758. ensure
  759. Result.is_integer_general_number
  760. Result.is_positive
  761. end
  762. numerator: INTEGER_GENERAL_NUMBER
  763. deferred
  764. end
  765. denominator: INTEGER_GENERAL_NUMBER
  766. deferred
  767. end
  768. feature {NUMBER} -- Implementation:
  769. frozen add_with_integer_64_number (other: INTEGER_64_NUMBER): NUMBER
  770. require
  771. other /= Void
  772. do
  773. Result := Current @+ other.to_integer_32
  774. ensure
  775. Result /= Void
  776. end
  777. add_with_big_integer_number (other: BIG_INTEGER_NUMBER): NUMBER
  778. require
  779. other /= Void
  780. deferred
  781. ensure
  782. Result /= Void
  783. end
  784. add_with_fraction_with_big_integer_number (other: FRACTION_WITH_BIG_INTEGER_NUMBER): NUMBER
  785. require
  786. other /= Void
  787. deferred
  788. ensure
  789. Result /= Void
  790. end
  791. multiply_with_integer_64_number (other: INTEGER_64_NUMBER): NUMBER
  792. require
  793. other /= Void
  794. do
  795. Result := Current @* other.to_integer_32
  796. ensure
  797. Result /= Void
  798. end
  799. multiply_with_big_integer_number (other: BIG_INTEGER_NUMBER): NUMBER
  800. require
  801. other /= Void
  802. deferred
  803. ensure
  804. Result /= Void
  805. end
  806. multiply_with_fraction_with_big_integer_number (other: FRACTION_WITH_BIG_INTEGER_NUMBER): NUMBER
  807. require
  808. other /= Void
  809. deferred
  810. ensure
  811. Result /= Void
  812. end
  813. greater_with_integer_64_number (other: INTEGER_64_NUMBER): BOOLEAN
  814. require
  815. other /= Void
  816. do
  817. Result := Current @> other.to_integer_32
  818. end
  819. greater_with_big_integer_number (other: BIG_INTEGER_NUMBER): BOOLEAN
  820. require
  821. other /= Void
  822. deferred
  823. end
  824. greater_with_fraction_with_big_integer_number (other: FRACTION_WITH_BIG_INTEGER_NUMBER): BOOLEAN
  825. require
  826. other /= Void
  827. deferred
  828. end
  829. gcd_with_integer_64_number (other: INTEGER_64_NUMBER): INTEGER_GENERAL_NUMBER
  830. require
  831. other /= Void
  832. deferred
  833. end
  834. gcd_with_big_integer_number (other: BIG_INTEGER_NUMBER): INTEGER_GENERAL_NUMBER
  835. require
  836. other /= Void
  837. deferred
  838. end
  839. feature {NUMBER, NUMBER_TOOLS}
  840. max_double: NUMBER
  841. local
  842. nt: NUMBER_TOOLS; tmp: STRING
  843. once
  844. tmp := "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  845. tmp.clear_count
  846. Maximum_real_64.append_in_format(tmp, 0)
  847. Result := nt.from_string(tmp)
  848. end
  849. min_double: NUMBER
  850. local
  851. nt: NUMBER_TOOLS; tmp: STRING
  852. once
  853. tmp := "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  854. tmp.clear_count
  855. Minimum_real_64.append_in_format(tmp, 0)
  856. Result := nt.from_string(tmp)
  857. end
  858. feature {NUMBER} -- To implement efficient calculus
  859. mutable_register1: MUTABLE_BIG_INTEGER
  860. once
  861. create Result.from_integer_64(0)
  862. end
  863. mutable_register2: MUTABLE_BIG_INTEGER
  864. once
  865. create Result.from_integer_64(0)
  866. end
  867. mutable_register3: MUTABLE_BIG_INTEGER
  868. once
  869. create Result.from_integer_64(0)
  870. end
  871. mutable_register4: MUTABLE_BIG_INTEGER
  872. once
  873. create Result.from_integer_64(0)
  874. end
  875. feature {}
  876. string_buffer: STRING
  877. once
  878. create Result.make(128)
  879. end
  880. unicode_string_buffer: UNICODE_STRING
  881. once
  882. create Result.make(128)
  883. end
  884. feature {} -- To create fractions
  885. from_two_integer (n, d: INTEGER_64): NUMBER
  886. require
  887. d /= 0
  888. local
  889. n_number, d_number: INTEGER_64_NUMBER
  890. do
  891. create n_number.make(n)
  892. create d_number.make(d)
  893. Result := from_two_integer_general_number(n_number, d_number)
  894. ensure
  895. Result @* d @= n
  896. end
  897. from_two_integer_general_number (n, d: INTEGER_GENERAL_NUMBER): NUMBER
  898. require
  899. n /= Void
  900. d /= Void
  901. not d.is_zero
  902. do
  903. if (n \\ d).is_zero then
  904. Result := n // d
  905. else
  906. create {FRACTION_WITH_BIG_INTEGER_NUMBER} Result.make(n, d)
  907. end
  908. ensure
  909. n.is_equal(Result * d)
  910. end
  911. from_integer_and_integer_general_number (n: INTEGER_64; d: INTEGER_GENERAL_NUMBER): NUMBER
  912. require
  913. d /= Void
  914. not d.is_zero
  915. local
  916. n_number: INTEGER_64_NUMBER
  917. do
  918. create n_number.make(n)
  919. Result := from_two_integer_general_number(n_number, d)
  920. end
  921. from_integer_general_number_and_integer (n: INTEGER_GENERAL_NUMBER; d: INTEGER_64): NUMBER
  922. require
  923. n /= Void
  924. d /= 0
  925. local
  926. d_number: INTEGER_64_NUMBER
  927. do
  928. create d_number.make(d)
  929. Result := from_two_integer_general_number(n, d_number)
  930. end
  931. invariant
  932. denominator.is_positive
  933. is_integer_general_number implies denominator.is_one
  934. not is_integer_general_number implies numerator.gcd(denominator) @= 1
  935. end -- class NUMBER
  936. --
  937. -- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
  938. --
  939. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  940. -- of this software and associated documentation files (the "Software"), to deal
  941. -- in the Software without restriction, including without limitation the rights
  942. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  943. -- copies of the Software, and to permit persons to whom the Software is
  944. -- furnished to do so, subject to the following conditions:
  945. --
  946. -- The above copyright notice and this permission notice shall be included in
  947. -- all copies or substantial portions of the Software.
  948. --
  949. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  950. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  951. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  952. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  953. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  954. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  955. -- THE SOFTWARE.