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