/src/lib/numeric/internal/integer_64_number.e

http://github.com/tybor/Liberty · Specman e · 372 lines · 287 code · 50 blank · 35 comment · 14 complexity · 3ee9d65dd140be8a0bd7c8006b3cd182 MD5 · raw file

  1. -- This file is part of a Liberty Eiffel library.
  2. -- See the full copyright at the end.
  3. --
  4. class INTEGER_64_NUMBER
  5. --
  6. -- To implement NUMBER (do not use this class, see NUMBER).
  7. --
  8. -- This is an INTEGER_64
  9. --
  10. inherit
  11. INTEGER_GENERAL_NUMBER
  12. create {ANY}
  13. make
  14. feature {ANY}
  15. is_zero: BOOLEAN
  16. do
  17. Result := value = 0
  18. end
  19. is_one: BOOLEAN
  20. do
  21. Result := value = 1
  22. end
  23. is_positive: BOOLEAN
  24. do
  25. Result := value > 0
  26. end
  27. is_negative: BOOLEAN
  28. do
  29. Result := value < 0
  30. end
  31. is_integer_value: BOOLEAN
  32. do
  33. Result := True
  34. end
  35. force_to_real_64: REAL_64
  36. do
  37. Result := value.force_to_real_64
  38. end
  39. append_in (buffer: STRING)
  40. do
  41. buffer.append(value.to_string)
  42. end
  43. append_in_unicode (buffer: UNICODE_STRING)
  44. do
  45. buffer.append(value.to_unicode_string)
  46. end
  47. prefix "-": INTEGER_GENERAL_NUMBER
  48. do
  49. if value = Minimum_integer_64 then
  50. mutable_register1.from_integer_64(Minimum_integer_64)
  51. mutable_register1.negate
  52. Result := mutable_register1.to_integer_general_number
  53. else
  54. create {INTEGER_64_NUMBER} Result.make(-value)
  55. end
  56. end
  57. infix "+" (other: NUMBER): NUMBER
  58. do
  59. Result := other @+ value
  60. end
  61. infix "@+" (other: INTEGER_64): NUMBER
  62. local
  63. sum: INTEGER_64
  64. do
  65. sum := value #+ other
  66. if value < 0 = (other < 0) implies sum < 0 = (value < 0) then
  67. -- no overflow
  68. create {INTEGER_64_NUMBER} Result.make(sum)
  69. else
  70. mutable_register1.from_integer_64(value)
  71. mutable_register1.add_integer_64(other)
  72. Result := mutable_register1.to_integer_general_number
  73. end
  74. end
  75. infix "*" (other: NUMBER): NUMBER
  76. do
  77. if is_zero then
  78. Result := zero
  79. else
  80. Result := other @* value
  81. end
  82. end
  83. infix "@*" (other: INTEGER_64): NUMBER
  84. do
  85. if other = 0 or else value = 0 then
  86. create {INTEGER_64_NUMBER} Result.make(0)
  87. elseif other = 1 then
  88. Result := Current
  89. elseif value = 1 then
  90. create {INTEGER_64_NUMBER} Result.make(other)
  91. else
  92. mutable_register1.from_integer_64(value)
  93. mutable_register2.from_integer_64(other)
  94. mutable_register1.multiply_to(mutable_register2, mutable_register3)
  95. Result := mutable_register3.to_integer_general_number
  96. end
  97. end
  98. infix "@/" (other: INTEGER_64): NUMBER
  99. local
  100. n, other_number: INTEGER_64_NUMBER; g: INTEGER_64
  101. do
  102. if value = 0 or else other = 1 then
  103. Result := Current
  104. elseif other = -1 then
  105. if value = Minimum_integer_64 then
  106. mutable_register1.from_integer_64(value)
  107. mutable_register1.negate
  108. Result := mutable_register1.to_integer_general_number
  109. else
  110. create {INTEGER_64_NUMBER} Result.make(-value)
  111. end
  112. else
  113. g := value.gcd(other)
  114. check
  115. g /= 0
  116. end
  117. if g = 1 then
  118. create other_number.make(other)
  119. if other < 0 then
  120. create {FRACTION_WITH_BIG_INTEGER_NUMBER} Result.make_simply(-Current, -other_number)
  121. else
  122. create {FRACTION_WITH_BIG_INTEGER_NUMBER} Result.make_simply(Current, other_number)
  123. end
  124. elseif other = g or else other = -g then
  125. Result := (value // other).to_number
  126. elseif other < 0 then
  127. create other_number.make(-(other // g))
  128. create n.make(-(value // g))
  129. create {FRACTION_WITH_BIG_INTEGER_NUMBER} Result.make_simply(n, other_number)
  130. else
  131. create other_number.make(other // g)
  132. create n.make(value // g)
  133. create {FRACTION_WITH_BIG_INTEGER_NUMBER} Result.make_simply(n, other_number)
  134. end
  135. end
  136. end
  137. infix "//" (other: NUMBER): NUMBER
  138. local
  139. oth: INTEGER_GENERAL_NUMBER
  140. do
  141. oth ::= other
  142. Result := oth.integer_divide_integer_64_number(Current)
  143. end
  144. infix "@//" (other: INTEGER_64): NUMBER
  145. do
  146. --|*** Must be rewrited directly with integer_64 (Vincent Croizier, 04/07/04) ***
  147. put_into_mutable_big_integer(mutable_register1)
  148. mutable_register2.from_integer_64(other)
  149. mutable_register1.divide_to(mutable_register2, mutable_register3, mutable_register4)
  150. Result := mutable_register3.to_integer_general_number
  151. end
  152. infix "\\" (other: NUMBER): NUMBER
  153. local
  154. oth: INTEGER_GENERAL_NUMBER
  155. do
  156. oth ::= other
  157. Result := oth.remainder_of_divide_integer_64_number(Current)
  158. end
  159. infix "@\\" (other: INTEGER_64): NUMBER
  160. do
  161. --|*** Must be rewrited directly with integer_64 (Vincent Croizier, 04/07/04) ***
  162. put_into_mutable_big_integer(mutable_register1)
  163. mutable_register2.from_integer_64(other)
  164. mutable_register1.divide_to(mutable_register2, mutable_register3, mutable_register4)
  165. Result := mutable_register4.to_integer_general_number
  166. end
  167. feature {ANY} -- Misc:
  168. hash_code: INTEGER
  169. do
  170. Result := value.hash_code
  171. end
  172. gcd (other: NUMBER): INTEGER_GENERAL_NUMBER
  173. do
  174. Result := other.gcd_with_integer_64_number(Current)
  175. end
  176. infix "@=" (other: INTEGER_64): BOOLEAN
  177. do
  178. Result := value = other
  179. end
  180. infix "@<" (other: INTEGER_64): BOOLEAN
  181. do
  182. Result := value < other
  183. end
  184. infix "@<=" (other: INTEGER_64): BOOLEAN
  185. do
  186. Result := value <= other
  187. end
  188. infix "@>" (other: INTEGER_64): BOOLEAN
  189. do
  190. Result := value > other
  191. end
  192. infix "@>=" (other: INTEGER_64): BOOLEAN
  193. do
  194. Result := value >= other
  195. end
  196. infix "#=" (other: REAL_64): BOOLEAN
  197. do
  198. --|*** Vincent, can you check ? *** (Dom Oct 2004) ***
  199. Result := value.force_to_real_64 = other
  200. end
  201. infix "#<" (other: REAL_64): BOOLEAN
  202. do
  203. --|*** Vincent, can you check ? *** (Dom Oct 2004) ***
  204. Result := value.force_to_real_64 < other
  205. end
  206. infix "#<=" (other: REAL_64): BOOLEAN
  207. do
  208. Result := value.force_to_real_64 <= other
  209. end
  210. infix "#>" (other: REAL_64): BOOLEAN
  211. do
  212. Result := value.force_to_real_64 > other
  213. --|*** Vincent, can you check ? *** (Dom Oct 2004) ***
  214. end
  215. infix "#>=" (other: REAL_64): BOOLEAN
  216. do
  217. Result := value.force_to_real_64 >= other
  218. --|*** Vincent, can you check ? *** (Dom Oct 2004) ***
  219. end
  220. infix "<" (other: NUMBER): BOOLEAN
  221. do
  222. Result := other @> value
  223. end
  224. is_equal (other: NUMBER): BOOLEAN
  225. local
  226. n2: like Current
  227. do
  228. if n2 ?:= other then
  229. n2 ::= other
  230. Result := value = n2.value
  231. end
  232. end
  233. inverse: NUMBER
  234. do
  235. if is_one or else Current @= -1 then
  236. Result := Current
  237. elseif is_negative then
  238. create {FRACTION_WITH_BIG_INTEGER_NUMBER} Result.make_simply(integer_general_number_one_negative, -Current)
  239. else
  240. create {FRACTION_WITH_BIG_INTEGER_NUMBER} Result.make_simply(integer_general_number_one, Current)
  241. end
  242. end
  243. feature {NUMBER} -- Implementation:
  244. value: INTEGER_64
  245. add_with_big_integer_number (other: BIG_INTEGER_NUMBER): NUMBER
  246. do
  247. Result := other @+ value
  248. end
  249. add_with_fraction_with_big_integer_number (other: FRACTION_WITH_BIG_INTEGER_NUMBER): NUMBER
  250. do
  251. Result := other @+ value
  252. end
  253. multiply_with_big_integer_number (other: BIG_INTEGER_NUMBER): NUMBER
  254. do
  255. Result := other @* value
  256. end
  257. multiply_with_fraction_with_big_integer_number (other: FRACTION_WITH_BIG_INTEGER_NUMBER): NUMBER
  258. do
  259. Result := other.multiply_with_integer_64_number(Current)
  260. end
  261. integer_divide_integer_64_number (other: INTEGER_64_NUMBER): INTEGER_GENERAL_NUMBER
  262. do
  263. Result ::= other @// value
  264. end
  265. integer_divide_big_integer_number (other: BIG_INTEGER_NUMBER): INTEGER_GENERAL_NUMBER
  266. do
  267. Result ::= other @// value
  268. end
  269. remainder_of_divide_integer_64_number (other: INTEGER_64_NUMBER): INTEGER_GENERAL_NUMBER
  270. do
  271. Result ::= other @\\ value
  272. end
  273. remainder_of_divide_big_integer_number (other: BIG_INTEGER_NUMBER): INTEGER_GENERAL_NUMBER
  274. do
  275. Result ::= other @\\ value
  276. end
  277. greater_with_big_integer_number (other: BIG_INTEGER_NUMBER): BOOLEAN
  278. do
  279. Result := other.is_negative
  280. end
  281. greater_with_fraction_with_big_integer_number (other: FRACTION_WITH_BIG_INTEGER_NUMBER): BOOLEAN
  282. do
  283. Result := other.denominator * Current > other.numerator
  284. end
  285. feature {NUMBER} -- Implementation:
  286. gcd_with_integer_64_number (other: INTEGER_64_NUMBER): INTEGER_64_NUMBER
  287. do
  288. create Result.make(value.gcd(other.value))
  289. end
  290. feature {NUMBER}
  291. put_into_mutable_big_integer (mut: MUTABLE_BIG_INTEGER)
  292. do
  293. mut.from_integer_64(value)
  294. end
  295. feature {}
  296. make (val: INTEGER_64)
  297. do
  298. value := val
  299. ensure
  300. Current.to_integer_64 = val
  301. end
  302. end -- class INTEGER_64_NUMBER
  303. --
  304. -- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
  305. --
  306. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  307. -- of this software and associated documentation files (the "Software"), to deal
  308. -- in the Software without restriction, including without limitation the rights
  309. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  310. -- copies of the Software, and to permit persons to whom the Software is
  311. -- furnished to do so, subject to the following conditions:
  312. --
  313. -- The above copyright notice and this permission notice shall be included in
  314. -- all copies or substantial portions of the Software.
  315. --
  316. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  317. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  318. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  319. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  320. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  321. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  322. -- THE SOFTWARE.