/src/lib/numeric/natural_general.e
Specman e | 383 lines | 232 code | 45 blank | 106 comment | 0 complexity | 995b20cecb0a9dab6358a85f5c905786 MD5 | raw file
1-- This file is part of a Liberty Eiffel library. 2-- See the full copyright at the end. 3-- 4deferred class NATURAL_GENERAL 5 -- 6 -- General natural number abstraction to share common code for NATURAL_8, NATURAL_16, NATURAL_32 and 7 -- NATURAL_64. 8 -- 9 -- All implementations have a limited size (8, 16, 32 or 64 bits). 10 -- As NATURAL_8, NATURAL_16, NATURAL_32 and NATURAL_64 are expanded classes, it is not possible to 11 -- expect any form of polymorphism (but you are sure to get the very best execution speed). 12 -- 13 -- See also INTEGER_8, INTEGER_16, INTEGER_32, INTEGER_64, NUMBER or MUTABLE_BIG_INTEGER. 14 -- 15 16inherit 17 COMPARABLE 18 redefine 19 is_equal, fill_tagged_out_memory, out_in_tagged_out_memory, infix ">", 20 infix "<=", infix ">=" 21 end 22 HASHABLE --| **** TODO change to NUMERIC when NATURAL integration is complete 23 redefine 24 fill_tagged_out_memory, out_in_tagged_out_memory 25 end 26 27insert 28 PLATFORM 29 redefine 30 is_equal, fill_tagged_out_memory, out_in_tagged_out_memory 31 end 32 33feature {ANY} 34 infix "+" (other: like Current): like Current 35 -- Sum with `other' (commutative). 36 external "built_in" 37 end 38 39 infix "-" (other: like Current): like Current 40 -- Result of subtracting `other'. 41 external "built_in" 42 end 43 44 infix "*" (other: like Current): like Current 45 -- Product by `other'. 46 external "built_in" 47 end 48 49 infix "/" (other: like Current): REAL 50 -- Division by `other'. 51 external "built_in" 52 end 53 54 infix "//" (other: like Current): like Current 55 -- Quotient of the Euclidian division of `Current' by `other'. 56 -- The corresponding remainder is given by infix "\\". 57 -- 58 -- See also infix "#//". 59 external "built_in" 60 end 61 62 infix "\\" (other: like Current): like Current 63 -- Remainder of the Euclidian division of `Current' by `other'. 64 -- By definition, `0 <= Result < other.abs'. 65 -- 66 -- See also infix "#\\", infix "//". 67 external "built_in" 68 end 69 70 infix "<" (other: like Current): BOOLEAN 71 external "built_in" 72 end 73 74 infix "<=" (other: like Current): BOOLEAN 75 external "built_in" 76 end 77 78 infix ">" (other: like Current): BOOLEAN 79 external "built_in" 80 end 81 82 infix ">=" (other: like Current): BOOLEAN 83 external "built_in" 84 end 85 86 is_odd: BOOLEAN 87 -- Is odd? 88 deferred 89 end 90 91 is_even: BOOLEAN 92 -- Is even? 93 deferred 94 end 95 96 is_equal (other: like Current): BOOLEAN 97 do 98 Result := Current = other 99 end 100 101feature {ANY} -- Conversions: 102 to_string: STRING 103 -- The decimal view of `Current' into a new allocated STRING. 104 -- For example, if `Current' is 3 the `Result' is "3". 105 -- 106 -- See also `append_in', `to_string_format', `to_unicode_string'. 107 do 108 string_buffer.clear_count 109 append_in(string_buffer) 110 Result := string_buffer.twin 111 end 112 113 to_unicode_string: UNICODE_STRING 114 -- The decimal view of `Current' into a new allocated UNICODE_STRING. 115 -- For example, if `Current' is -1 the `Result' is U"-1". 116 -- 117 -- See also `append_in_unicode', `to_unicode_string_format', `to_string'. 118 do 119 unicode_string_buffer.clear_count 120 append_in_unicode(unicode_string_buffer) 121 Result := unicode_string_buffer.twin 122 end 123 124 append_in_format (buffer: STRING; s: INTEGER) 125 -- Append in the `buffer' the equivalent of `to_string_format'. 126 -- If you look for performances, you should always prefer `append_in_format' which allow you 127 -- to recycle a unique common `buffer' (each call of `to_string_format' allocate a new object!). 128 -- 129 -- See also `append_in', `append_in_unicode', `append_in_unicode_format'. 130 require 131 to_string.count <= s 132 local 133 i: INTEGER 134 do 135 string_buffer.clear_count 136 append_in(string_buffer) 137 from 138 i := s - string_buffer.count 139 until 140 i <= 0 141 loop 142 buffer.extend(' ') 143 i := i - 1 144 end 145 buffer.append(string_buffer) 146 ensure 147 buffer.count >= old buffer.count + s 148 end 149 150 append_in_unicode_format (buffer: UNICODE_STRING; s: INTEGER) 151 -- Append in the `buffer' the equivalent of `to_unicode_string_format'. 152 -- If you look for performances, you should always prefer `append_in_unicode_format' which allow 153 -- you to recycle a unique common `buffer' (each call of `to_unicode_string_format' allocate a 154 -- new object!). 155 -- 156 -- See also `append_in_format', `append_in', `append_in_format'. 157 require 158 to_string.count <= s 159 local 160 i: INTEGER 161 do 162 unicode_string_buffer.clear_count 163 append_in_unicode(unicode_string_buffer) 164 from 165 i := s - unicode_string_buffer.count 166 until 167 i <= 0 168 loop 169 buffer.extend(' '.code) 170 i := i - 1 171 end 172 buffer.append(unicode_string_buffer) 173 ensure 174 buffer.count >= old buffer.count + s 175 end 176 177 decimal_digit: CHARACTER 178 -- Gives the corresponding CHARACTER for range 0..9. 179 -- 180 -- See also `hexadecimal_digit'. 181 deferred 182 ensure 183 (once "0123456789").has(Result) 184 end 185 186 hexadecimal_digit: CHARACTER 187 -- Gives the corresponding CHARACTER for range 0..15. 188 -- 189 -- See also `decimal_digit'. 190 deferred 191 ensure 192 (once "0123456789ABCDEF").has(Result) 193 end 194 195 to_character: CHARACTER 196 -- Return the corresponding ASCII character. 197 -- 198 -- See also `to_boolean', `to_number', `to_string'. 199 deferred 200 end 201 202 to_number: NUMBER 203 -- Convert `Current' into a new allocated NUMBER. 204 -- 205 -- See also `to_boolean', `to_string', `to_character', `to_hexadecimal'. 206 deferred 207 ensure 208 Result.to_string.is_equal(to_string) 209 end 210 211feature {ANY} -- Modular arithmetic (these wrap around on overflow) 212 infix "#+" (other: like Current): like Current 213 external "built_in" 214 end 215 216 infix "#-" (other: like Current): like Current 217 external "built_in" 218 end 219 220 infix "#\\" (other: like Current): like Current 221 external "built_in" 222 end 223 224 infix "#//" (other: like Current): like Current 225 external "built_in" 226 end 227 228feature {ANY} -- Object printing 229 out_in_tagged_out_memory, fill_tagged_out_memory 230 do 231 Current.append_in(tagged_out_memory) 232 end 233 234 to_hexadecimal: STRING 235 do 236 string_buffer.clear_count 237 to_hexadecimal_in(string_buffer) 238 Result := string_buffer.twin 239 end 240 241 to_hexadecimal_in (buffer: STRING) 242 local 243 index, timez: INTEGER; 244 value, val_mask: like Current 245 do 246 from 247 value := Current 248 timez := object_size * 2 249 index := buffer.count + timez 250 buffer.extend_multiple(' ', timez) 251 until 252 timez = 0 253 loop 254 val_mask := (value |>> 4) |<< 4 255 buffer.put((value - val_mask).hexadecimal_digit, index) 256 index := index - 1 257 value := value |>> 4 258 timez := timez - 1 259 end 260 end 261 262 append_in (buffer: STRING) 263 -- Append in the `buffer' the equivalent of `to_string'. 264 -- If you look for performances, you should always prefer `append_in' which allow you to recycle 265 -- a unique common `buffer' (each call of `to_string' allocate a new object!). 266 -- 267 -- See also `append_in_format', `append_in_unicode', `append_in_unicode_format', `to_hexadecimal_in'. 268 require 269 buffer /= Void 270 deferred 271 end 272 273 append_in_unicode (buffer: UNICODE_STRING) 274 -- Append in the `buffer' the equivalent of `to_unicode_string'. 275 -- If you look for performances, you should always prefer `append_in_unicode' which allow you to recycle 276 -- a unique common `buffer' (each call of `to_unicode_string' allocate a new object!). 277 -- 278 -- See also `append_in_unicode_format', `append_in', `append_in_format', `to_hexadecimal_in'. 279 require 280 buffer /= Void 281 deferred 282 end 283 284feature {ANY} -- Bitwise Logical Operators: 285 infix "#>>", bit_rotate_right (s: INTEGER_8): like Current 286 -- Rotate by `s' positions right. 287 -- 288 -- See also `bit_rotate_left' and `bit_rotate'. 289 require 290 s.in_range(1, bit_count - 1) 291 external "built_in" 292 end 293 294 infix "#<<", bit_rotate_left (s: INTEGER_8): like Current 295 -- Rotate by `s' positions left. 296 -- 297 -- See also `bit_rotate_right' and `bit_rotate'. 298 require 299 s.in_range(1, bit_count - 1) 300 external "built_in" 301 end 302 303 bit_rotate (s: INTEGER_8): like Current 304 -- Rotate by `s' positions (positive `s' shifts right, negative left 305 -- 306 -- See also `bit_rotate_right' and `bit_rotate_left'. 307 require 308 s.in_range(- (bit_count - 1), bit_count - 1) 309 external "built_in" 310 end 311 312 prefix "~", bit_not: like Current 313 -- One's complement of `Current'. 314 external "built_in" 315 end 316 317 infix "&", bit_and (other: like Current): like Current 318 -- Bitwise logical and of `Current' with `other'. 319 external "built_in" 320 end 321 322 infix "|", bit_or (other: like Current): like Current 323 -- Bitwise logical inclusive or of `Current' with `other'. 324 external "built_in" 325 end 326 327 bit_xor (other: like Current): like Current 328 -- Bitwise logical exclusive or of `Current' with `other'. 329 external "built_in" 330 end 331 332 infix "|>>", bit_shift_right (s: INTEGER_8): like Current 333 -- Shift by `s' positions right (sign bit copied) bits falling off the end are lost. 334 external "built_in" 335 end 336 337 infix "|<<", bit_shift_left (s: INTEGER_8): like Current 338 -- Shift by `s' positions left bits falling off the end are lost. 339 external "built_in" 340 end 341 342feature {ANY} -- Size query 343 bit_count: INTEGER_8 344 -- The number of bits used to store the value of Current 345 -- (it is 8 for NATURAL_8, 16 for NATURAL_16 and so on) 346 -- This is actually used only for assertion here, in NATURAL_GENERAL. 347 deferred 348 ensure 349 Result = (object_size * 8) 350 end 351 352feature {} 353 string_buffer: STRING 354 once 355 create Result.make(128) 356 end 357 358 unicode_string_buffer: UNICODE_STRING 359 once 360 create Result.make(128) 361 end 362 363end -- class NATURAL_GENERAL 364-- 365-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file. 366-- 367-- Permission is hereby granted, free of charge, to any person obtaining a copy 368-- of this software and associated documentation files (the "Software"), to deal 369-- in the Software without restriction, including without limitation the rights 370-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 371-- copies of the Software, and to permit persons to whom the Software is 372-- furnished to do so, subject to the following conditions: 373-- 374-- The above copyright notice and this permission notice shall be included in 375-- all copies or substantial portions of the Software. 376-- 377-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 378-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 379-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 380-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 381-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 382-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 383-- THE SOFTWARE.