PageRenderTime 37ms CodeModel.GetById 23ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/src/lib/numeric/natural_64.e

http://github.com/tybor/Liberty
Specman e | 320 lines | 241 code | 33 blank | 46 comment | 4 complexity | 771d37d84fcc2c855433abb818aad49d MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4expanded class NATURAL_64
  5
  6insert
  7   NATURAL_GENERAL
  8      redefine infix "//", infix "\\"
  9      end
 10
 11feature {ANY} -- Explicit conversions:
 12   fit_natural_8: BOOLEAN
 13         -- Does `Current' fit in NATURAL_8?
 14      do
 15         Result := Current <= 255.to_natural_64
 16      ensure
 17         Result = (Current <= 255.to_natural_64)
 18      end
 19
 20   to_natural_8: NATURAL_8
 21         -- Explicit conversion to NATURAL_8.
 22      require
 23         fit_natural_8
 24      external "built_in"
 25      ensure
 26         Result.to_natural_64 = Current
 27      end
 28
 29   fit_natural_16: BOOLEAN
 30         -- Does `Current' fit in NATURAL_16?
 31      do
 32         Result := Current <= 65535.to_natural_64
 33      ensure
 34         Result = (Current <= 65535.to_natural_64)
 35      end
 36
 37   to_natural_16: NATURAL_16
 38         -- Explicit conversion to NATURAL_16.
 39      require
 40         fit_natural_16
 41      external "built_in"
 42      ensure
 43         Result.to_natural_64 = Current
 44      end
 45
 46   fit_natural_32: BOOLEAN
 47         -- Does `Current' fit in NATURAL_32?
 48      do
 49         Result := Current <= 2147483647.to_natural_64
 50      ensure
 51         Result = (Current <= 2147483647.to_natural_64)
 52      end
 53
 54   to_natural_32: NATURAL_32
 55         -- Explicit conversion to NATURAL_32.
 56      require
 57         fit_natural_32
 58      external "built_in"
 59      ensure
 60         Result.to_natural_64 = Current
 61      end
 62
 63   fit_integer_8: BOOLEAN
 64         -- Does `Current' fit in INTEGER_8?
 65      do
 66         Result := Current <= 127.to_natural_64
 67      ensure
 68         Result = (Current <= 127.to_natural_64)
 69      end
 70
 71   to_integer_8: INTEGER_8
 72         -- Explicit conversion to INTEGER_8.
 73      require
 74         fit_integer_8
 75      external "built_in"
 76      ensure
 77         Result.to_natural_64 = Current
 78      end
 79
 80   fit_integer_16: BOOLEAN
 81         -- Does `Current' fit in INTEGER_16?
 82      do
 83         Result := Current <= 32767.to_natural_64
 84      ensure
 85         Result = (Current <= 32767.to_natural_64)
 86      end
 87
 88   to_integer_16: INTEGER_16
 89         -- Explicit conversion to INTEGER_16.
 90      require
 91         fit_integer_16
 92      external "built_in"
 93      ensure
 94         Result.to_natural_64 = Current
 95      end
 96
 97   fit_integer_32: BOOLEAN
 98         -- Does `Current' fit in INTEGER_32?
 99      do
100         Result := Current <= 2147483647.to_natural_64
101      ensure
102         Result = (Current <= 2147483647.to_natural_64)
103      end
104
105   to_integer_32: INTEGER_32
106         -- Explicit conversion to INTEGER_32.
107      require
108         fit_integer_32
109      external "built_in"
110      ensure
111         Result.to_natural_64 = Current
112      end
113
114   fit_integer_64: BOOLEAN
115         -- Does `Current' fit in INTEGER_64?
116      do
117         Result := Current <= 9223372036854775807.to_natural_64
118      ensure
119         Result = (Current <= 9223372036854775807.to_natural_64)
120      end
121
122   to_integer_64: INTEGER_64
123         -- Explicit conversion to INTEGER_64.
124      require
125         fit_integer_64
126      external "built_in"
127      ensure
128          Result.to_natural_64 = Current
129      end
130
131   fit_real_32: BOOLEAN
132         -- Does `Current' fit in REAL_32?
133      do
134         Result := fit_natural_32 and then to_natural_32.fit_real_32
135      end
136
137   to_real_32: REAL_32
138         -- Explicit conversion to REAL_32.
139      require
140         fit_real_32
141      do
142         Result := to_integer_64.force_to_real_32
143      ensure
144         Result.force_to_natural_64 = Current
145      end
146
147   fit_real_64: BOOLEAN
148         -- Does `Current' fit in REAL_64?
149      do
150         Result := natural_64_fit_real_64(Current)
151      end
152
153   to_real_64: REAL_64
154         -- Explicit conversion to REAL_64.
155      require
156         fit_real_64
157      do
158         Result := to_integer_64.to_real_64
159      ensure
160         Result.force_to_natural_64 = Current
161      end
162
163feature {ANY}
164   infix "//" (other: like Current): like Current
165      require
166         other /= 0.to_natural_64
167      external "built_in"
168      end
169
170   infix "\\" (other: like Current): like Current
171      require
172         other /= 0.to_natural_64
173      external "built_in"
174      end
175
176   is_odd: BOOLEAN
177      do
178         Result := (Current #\\ 2.to_natural_64) = 1.to_natural_64
179      end
180
181   is_even: BOOLEAN
182      do
183         Result := (Current #\\ 2.to_natural_64) = 0.to_natural_64
184      end
185
186   hash_code: INTEGER
187      do
188         if Current.fit_integer_64 then
189            Result := to_integer_64.hash_code
190         else
191            Result := ((Current - 1.to_natural_64) // 2.to_natural_64).hash_code
192         end
193      end
194
195   append_in (buffer: STRING)
196      local
197         val: like Current; i, idx: INTEGER
198      do
199         if Current = 0.to_natural_64 then
200            buffer.extend('0')
201         else
202            from
203               val := Current
204               -- Save the position of first character in the buffer.
205               i := buffer.count + 1
206            until
207               val = 0.to_natural_64
208            loop
209               buffer.extend((val #\\ 10.to_natural_64).decimal_digit)
210               val := val #// 10.to_natural_64
211            end
212            -- Change character order.
213            from
214               idx := buffer.count
215            until
216               i >= idx
217            loop
218               buffer.swap(i, idx)
219               idx := idx - 1
220               i := i + 1
221            end
222         end
223      end
224
225   append_in_unicode (buffer: UNICODE_STRING)
226      local
227         val: like Current; i, idx: INTEGER
228      do
229         if Current = 0.to_natural_64 then
230            buffer.extend('0'.code)
231         else
232            from
233               val := Current
234               -- Save the position of first character in the buffer.
235               i := buffer.count + 1
236            until
237               val = 0.to_natural_64
238            loop
239               buffer.extend((val #\\ 10.to_natural_64).decimal_digit.code)
240               val := val #// 10.to_natural_64
241            end
242            -- Change character order.
243            from
244               idx := buffer.count
245            until
246               i >= idx
247            loop
248               buffer.swap(i, idx)
249               idx := idx - 1
250               i := i + 1
251            end
252         end
253      end
254
255   decimal_digit: CHARACTER
256      require
257         in_range(0.to_natural_64, 9.to_natural_64)
258      do
259         Result := to_integer_8.hexadecimal_digit
260      end
261
262   hexadecimal_digit: CHARACTER
263      require
264         in_range(0.to_natural_64, 15.to_natural_64)
265      do
266         Result := to_integer_8.hexadecimal_digit
267      end
268
269   to_character: CHARACTER
270      require
271         to_integer_16 <= Maximum_character_code
272      do
273         Result := to_integer_16.to_character
274      end
275
276   to_number: NUMBER
277      do
278         -- Well, there is probably a better way, but this should work:
279         if Current.fit_integer_64 then
280            Result := to_integer_64.to_number
281         elseif is_even then
282            Result := (Current // 2.to_natural_64).to_integer_64.to_number @* 2
283         else
284            Result := (Current - 1.to_natural_64).to_number @+ 1
285         end
286      end
287
288   bit_count: INTEGER_8 64
289
290feature {}
291   natural_64_fit_real_64 (natural_64: NATURAL_64): BOOLEAN
292      external "plug_in"
293      alias "{
294         location: "${sys}/runtime"
295         module_name: "natural_fit_real"
296         feature_name: "natural_64_fit_real_64"
297         }"
298      end
299
300end -- NATURAL_64
301--
302-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
303--
304-- Permission is hereby granted, free of charge, to any person obtaining a copy
305-- of this software and associated documentation files (the "Software"), to deal
306-- in the Software without restriction, including without limitation the rights
307-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
308-- copies of the Software, and to permit persons to whom the Software is
309-- furnished to do so, subject to the following conditions:
310--
311-- The above copyright notice and this permission notice shall be included in
312-- all copies or substantial portions of the Software.
313--
314-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
315-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
316-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
317-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
318-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
319-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
320-- THE SOFTWARE.