7b781481b6a2f4ad0dec56f3ec2fbbc0b1f8bfdf
[nit.git] / lib / standard / fixed_ints.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # This file is free software, which comes along with NIT. This software is
4 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
5 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
6 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
7 # is kept unaltered, and a notification of the changes is added.
8 # You are allowed to redistribute it and sell it, alone or is a part of
9 # another product.
10
11 # Basic integers of fixed-precision
12 #
13 # All classes defined here have C-equivalents and the semantics of their
14 # operations are the same as C's
15 #
16 # * Int8 => int8_t
17 # * Int16 => int16_t
18 # * UInt16 => uint16_t
19 # * Int32 => int32_t
20 # * UInt32 => uint32_t
21 #
22 # NOTE: No UInt8 is provided as Byte is the same
23 # SEE: kernel::Byte
24 #
25 # HOW TO USE:
26 # All classes can be instanciated via a literal rule.
27 # Namely, a suffix to append after the literal integer.
28 #
29 # * Int8 => i8
30 # * Byte => u8
31 # * Int16 => i16
32 # * UInt16 => u16
33 # * Int32 => i32
34 # * UInt32 => u32
35 module fixed_ints
36
37 import text
38
39 in "C" `{
40 #include <inttypes.h>
41 `}
42
43 redef class Numeric
44
45 # The Int8 equivalent of `self`
46 #
47 # assert (-1).to_i8 == 0xFFFFi8
48 # assert (1.9).to_i8 == 1i8
49 fun to_i8: Int8 do return self.to_i.to_i8
50
51 # The Int16 equivalent of `self`
52 #
53 # assert (-1).to_i16 == 0xFFFFi16
54 # assert (1.9).to_i16 == 1i16
55 fun to_i16: Int16 do return self.to_i.to_i16
56
57 # The UInt16 equivalent of `self`
58 #
59 # assert (-1).to_u16 == 0xFFFFu16
60 # assert (1.9).to_u16 == 1u16
61 fun to_u16: UInt16 do return self.to_i.to_u16
62
63 # The Int32 equivalent of `self`
64 #
65 # assert (-1).to_i32 == 0xFFFFFFFFi32
66 # assert (1.9).to_i32 == 1i32
67 fun to_i32: Int32 do return self.to_i.to_i32
68
69 # The UInt32 equivalent of `self`
70 #
71 # assert (-1).to_u32 == 0xFFFFFFFFu32
72 # assert (1.9).to_u32 == 1u32
73 fun to_u32: UInt32 do return self.to_i.to_u32
74
75 end
76
77 redef class Float
78 redef fun to_i8 is intern
79 redef fun to_i16 is intern
80 redef fun to_u16 is intern
81 redef fun to_i32 is intern
82 redef fun to_u32 is intern
83 end
84
85 redef class Byte
86 redef fun to_i8 is intern
87 redef fun to_i16 is intern
88 redef fun to_u16 is intern
89 redef fun to_i32 is intern
90 redef fun to_u32 is intern
91 end
92
93 redef class Int
94 redef fun to_i8 is intern
95 redef fun to_i16 is intern
96 redef fun to_u16 is intern
97 redef fun to_i32 is intern
98 redef fun to_u32 is intern
99 end
100
101 # Native 8-bit signed integer.
102 # Same as a C `int8_t`
103 universal Int8
104 super Discrete
105 super Numeric
106
107 redef type OTHER: Int8
108
109 redef fun successor(i) do return self + i.to_i8
110 redef fun predecessor(i) do return self - i.to_i8
111
112 redef fun object_id is intern
113 redef fun hash do return self.to_i
114 redef fun ==(i) is intern
115 redef fun !=(i) is intern
116 redef fun output is intern
117
118 redef fun <=(i) is intern
119 redef fun <(i) is intern
120 redef fun >=(i) is intern
121 redef fun >(i) is intern
122 redef fun +(i) is intern
123
124 # assert -1i8 == 0xFFi8
125 # assert -0i8 == 0x00i8
126 redef fun - is intern
127 redef fun -(i) is intern
128 redef fun *(i) is intern
129 redef fun /(i) is intern
130
131 # Modulo of `self` with `i`.
132 #
133 # Returns the remainder of division of `self` by `i`.
134 #
135 # assert 5i8 % 2i8 == 1i8
136 # assert 10i8 % 2i8 == 0i8
137 fun %(i: Int8): Int8 is intern
138
139 redef fun zero do return 0.to_i8
140 redef fun value_of(val) do return val.to_i8
141
142 # `i` bits shift to the left
143 #
144 # assert 5i8 << 1 == 10i8
145 fun <<(i: Int): Int8 is intern
146
147 # `i` bits shift to the right
148 #
149 # assert 5i8 >> 1 == 2i8
150 fun >>(i: Int): Int8 is intern
151
152 redef fun to_i is intern
153 redef fun to_f is intern
154 redef fun to_b is intern
155 redef fun to_i8 do return self
156 redef fun to_i16 is intern
157 redef fun to_u16 is intern
158 redef fun to_i32 is intern
159 redef fun to_u32 is intern
160
161 redef fun distance(i) do return (self - i).to_i
162
163 redef fun <=>(other)
164 do
165 if self < other then
166 return -1
167 else if other < self then
168 return 1
169 else
170 return 0
171 end
172 end
173
174 redef fun is_between(c, d)
175 do
176 if self < c or d < self then
177 return false
178 else
179 return true
180 end
181 end
182
183 redef fun max(other)
184 do
185 if self < other then
186 return other
187 else
188 return self
189 end
190 end
191
192 redef fun min(c)
193 do
194 if c < self then
195 return c
196 else
197 return self
198 end
199 end
200
201 # Returns the result of a binary AND operation on `self` and `i`
202 #
203 # assert 0x10i8 & 0x01i8 == 0i8
204 fun &(i: Int8): Int8 is intern
205
206 # Returns the result of a binary OR operation on `self` and `i`
207 #
208 # assert 0x10i8 | 0x01i8 == 0x11i8
209 fun |(i: Int8): Int8 is intern
210
211 # Returns the result of a binary XOR operation on `self` and `i`
212 #
213 # assert 0x101i8 ^ 0x110i8 == 0x11i8
214 fun ^(i: Int8): Int8 is intern
215
216 # Returns the 1's complement of `self`
217 #
218 # assert ~0x2Fi8 == 0xD0i8
219 fun ~: Int8 is intern
220
221 # C function to calculate the length of the `NativeString` to receive `self`
222 private fun to_s_len: Int `{
223 return snprintf(NULL, 0, "%"PRIi8, self);
224 `}
225
226 # C function to convert a nit Int to a NativeString (char*)
227 private fun native_to_s(nstr: NativeString, strlen: Int) `{
228 snprintf(nstr, strlen, "%"PRIi8, self);
229 `}
230
231 # Displayable Int8
232 #
233 # assert 1i8.to_s == "1"
234 # assert (-123i8).to_s == "-123"
235 redef fun to_s do
236 var nslen = to_s_len
237 var ns = new NativeString(nslen + 1)
238 ns[nslen] = 0u8
239 native_to_s(ns, nslen + 1)
240 return ns.to_s_with_length(nslen)
241 end
242 end
243
244 # Native 16-bit signed integer.
245 # Same as a C `int16_t`
246 universal Int16
247 super Discrete
248 super Numeric
249
250 redef type OTHER: Int16
251
252 redef fun successor(i) do return self + i.to_i16
253 redef fun predecessor(i) do return self - i.to_i16
254
255 redef fun object_id is intern
256 redef fun hash do return self.to_i
257 redef fun ==(i) is intern
258 redef fun !=(i) is intern
259 redef fun output is intern
260
261 redef fun <=(i) is intern
262 redef fun <(i) is intern
263 redef fun >=(i) is intern
264 redef fun >(i) is intern
265 redef fun +(i) is intern
266
267 # assert -1i16 == 0xFFFFi16
268 # assert -0i16 == 0i16
269 redef fun - is intern
270 redef fun -(i) is intern
271 redef fun *(i) is intern
272 redef fun /(i) is intern
273
274 # Modulo of `self` with `i`.
275 #
276 # Returns the remainder of division of `self` by `i`.
277 #
278 # assert 5i16 % 2i16 == 1i16
279 # assert 10i16 % 2i16 == 0i16
280 fun %(i: Int16): Int16 is intern
281
282 redef fun zero do return 0.to_i16
283 redef fun value_of(val) do return val.to_i16
284
285 # `i` bits shift to the left
286 #
287 # assert 5i16 << 1 == 10i16
288 fun <<(i: Int): Int16 is intern
289
290 # `i` bits shift to the right
291 #
292 # assert 5i16 >> 1 == 2i16
293 fun >>(i: Int): Int16 is intern
294
295 redef fun to_i is intern
296 redef fun to_f is intern
297 redef fun to_b is intern
298 redef fun to_i8 is intern
299 redef fun to_i16 do return self
300 redef fun to_u16 is intern
301 redef fun to_i32 is intern
302 redef fun to_u32 is intern
303
304 redef fun distance(i) do return (self - i).to_i
305
306 redef fun <=>(other)
307 do
308 if self < other then
309 return -1
310 else if other < self then
311 return 1
312 else
313 return 0
314 end
315 end
316
317 redef fun is_between(c, d)
318 do
319 if self < c or d < self then
320 return false
321 else
322 return true
323 end
324 end
325
326 redef fun max(other)
327 do
328 if self < other then
329 return other
330 else
331 return self
332 end
333 end
334
335 redef fun min(c)
336 do
337 if c < self then
338 return c
339 else
340 return self
341 end
342 end
343
344 # Returns the result of a binary AND operation on `self` and `i`
345 #
346 # assert 0x10i16 & 0x01i16 == 0i16
347 fun &(i: Int16): Int16 is intern
348
349 # Returns the result of a binary OR operation on `self` and `i`
350 #
351 # assert 0x10i16 | 0x01i16 == 0x11i16
352 fun |(i: Int16): Int16 is intern
353
354 # Returns the result of a binary XOR operation on `self` and `i`
355 #
356 # assert 0x101i16 ^ 0x110i16 == 0x11i16
357 fun ^(i: Int16): Int16 is intern
358
359 # Returns the 1's complement of `self`
360 #
361 # assert ~0x2Fi16 == 0xFFD0i16
362 fun ~: Int16 is intern
363
364 # C function to calculate the length of the `NativeString` to receive `self`
365 private fun to_s_len: Int `{
366 return snprintf(NULL, 0, "%"PRIi16, self);
367 `}
368
369 # C function to convert a nit Int to a NativeString (char*)
370 private fun native_to_s(nstr: NativeString, strlen: Int) `{
371 snprintf(nstr, strlen, "%"PRIi16, self);
372 `}
373
374 # Displayable Int16
375 #
376 # assert 1i16.to_s == "1"
377 # assert (-123i16).to_s == "-123"
378 redef fun to_s do
379 var nslen = to_s_len
380 var ns = new NativeString(nslen + 1)
381 ns[nslen] = 0u8
382 native_to_s(ns, nslen + 1)
383 return ns.to_s_with_length(nslen)
384 end
385 end
386
387 # Native 16-bit unsigned integer.
388 # Same as a C `uint16_t`
389 universal UInt16
390 super Discrete
391 super Numeric
392
393 redef type OTHER: UInt16
394
395 redef fun successor(i) do return self + i.to_u16
396 redef fun predecessor(i) do return self - i.to_u16
397
398 redef fun object_id is intern
399 redef fun hash do return self.to_i
400 redef fun ==(i) is intern
401 redef fun !=(i) is intern
402 redef fun output is intern
403
404 redef fun <=(i) is intern
405 redef fun <(i) is intern
406 redef fun >=(i) is intern
407 redef fun >(i) is intern
408 redef fun +(i) is intern
409
410 # assert -1u16 == 0xFFFFu16
411 # assert -0u16 == 0u16
412 redef fun - is intern
413 redef fun -(i) is intern
414 redef fun *(i) is intern
415 redef fun /(i) is intern
416
417 # Modulo of `self` with `i`.
418 #
419 # Returns the remainder of division of `self` by `i`.
420 #
421 # assert 5u16 % 2u16 == 1u16
422 # assert 10u16 % 2u16 == 0u16
423 fun %(i: UInt16): UInt16 is intern
424
425 redef fun zero do return 0.to_u16
426 redef fun value_of(val) do return val.to_u16
427
428 # `i` bits shift to the left
429 #
430 # assert 5u16 << 1 == 10u16
431 fun <<(i: Int): UInt16 is intern
432
433 # `i` bits shift to the right
434 #
435 # assert 5u16 >> 1 == 2u16
436 fun >>(i: Int): UInt16 is intern
437
438 redef fun to_i is intern
439 redef fun to_f is intern
440 redef fun to_b is intern
441 redef fun to_i8 is intern
442 redef fun to_i16 is intern
443 redef fun to_u16 do return self
444 redef fun to_i32 is intern
445 redef fun to_u32 is intern
446
447 redef fun distance(i) do return (self - i).to_i
448
449 redef fun <=>(other)
450 do
451 if self < other then
452 return -1
453 else if other < self then
454 return 1
455 else
456 return 0
457 end
458 end
459
460 redef fun is_between(c, d)
461 do
462 if self < c or d < self then
463 return false
464 else
465 return true
466 end
467 end
468
469 redef fun max(other)
470 do
471 if self < other then
472 return other
473 else
474 return self
475 end
476 end
477
478 redef fun min(c)
479 do
480 if c < self then
481 return c
482 else
483 return self
484 end
485 end
486
487 # Returns the result of a binary AND operation on `self` and `i`
488 #
489 # assert 0x10u16 & 0x01u16 == 0u16
490 fun &(i: UInt16): UInt16 is intern
491
492 # Returns the result of a binary OR operation on `self` and `i`
493 #
494 # assert 0x10u16 | 0x01u16 == 0x11u16
495 fun |(i: UInt16): UInt16 is intern
496
497 # Returns the result of a binary XOR operation on `self` and `i`
498 #
499 # assert 0x101u16 ^ 0x110u16 == 0x11u16
500 fun ^(i: UInt16): UInt16 is intern
501
502 # Returns the 1's complement of `self`
503 #
504 # assert ~0x2Fu16 == 0xFFD0u16
505 fun ~: UInt16 is intern
506
507 # C function to calculate the length of the `NativeString` to receive `self`
508 private fun to_s_len: Int `{
509 return snprintf(NULL, 0, "%"PRIu16, self);
510 `}
511
512 # C function to convert a nit Int to a NativeString (char*)
513 private fun native_to_s(nstr: NativeString, strlen: Int) `{
514 snprintf(nstr, strlen, "%"PRIu16, self);
515 `}
516
517 # Displayable UInt16
518 #
519 # assert 1u16.to_s == "1"
520 # assert (-123u16).to_s == "65413"
521 redef fun to_s do
522 var nslen = to_s_len
523 var ns = new NativeString(nslen + 1)
524 ns[nslen] = 0u8
525 native_to_s(ns, nslen + 1)
526 return ns.to_s_with_length(nslen)
527 end
528 end
529
530
531 # Native 32-bit signed integer.
532 # Same as a C `int32_t`
533 universal Int32
534 super Discrete
535 super Numeric
536
537 redef type OTHER: Int32
538
539 redef fun successor(i) do return self + i.to_i32
540 redef fun predecessor(i) do return self - i.to_i32
541
542 redef fun object_id is intern
543 redef fun hash do return self.to_i
544 redef fun ==(i) is intern
545 redef fun !=(i) is intern
546 redef fun output is intern
547
548 redef fun <=(i) is intern
549 redef fun <(i) is intern
550 redef fun >=(i) is intern
551 redef fun >(i) is intern
552 redef fun +(i) is intern
553
554 # assert -1i32 == 0xFFFFFFFFi32
555 # assert -0i32 == 0x00i32
556 redef fun - is intern
557 redef fun -(i) is intern
558 redef fun *(i) is intern
559 redef fun /(i) is intern
560
561 # Modulo of `self` with `i`.
562 #
563 # Returns the remainder of division of `self` by `i`.
564 #
565 # assert 5i32 % 2i32 == 1i32
566 # assert 10i32 % 2i32 == 0i32
567 fun %(i: Int32): Int32 is intern
568
569 redef fun zero do return 0.to_i32
570 redef fun value_of(val) do return val.to_i32
571
572 # `i` bits shift to the left
573 #
574 # assert 5i32 << 1 == 10i32
575 fun <<(i: Int): Int32 is intern
576
577 # `i` bits shift to the right
578 #
579 # assert 5i32 >> 1 == 2i32
580 fun >>(i: Int): Int32 is intern
581
582 redef fun to_i is intern
583 redef fun to_f is intern
584 redef fun to_b is intern
585 redef fun to_i8 is intern
586 redef fun to_i16 is intern
587 redef fun to_u16 is intern
588 redef fun to_i32 do return self
589 redef fun to_u32 is intern
590
591 redef fun distance(i) do return (self - i).to_i
592
593 redef fun <=>(other)
594 do
595 if self < other then
596 return -1
597 else if other < self then
598 return 1
599 else
600 return 0
601 end
602 end
603
604 redef fun is_between(c, d)
605 do
606 if self < c or d < self then
607 return false
608 else
609 return true
610 end
611 end
612
613 redef fun max(other)
614 do
615 if self < other then
616 return other
617 else
618 return self
619 end
620 end
621
622 redef fun min(c)
623 do
624 if c < self then
625 return c
626 else
627 return self
628 end
629 end
630
631 # Returns the result of a binary AND operation on `self` and `i`
632 #
633 # assert 0x10i32 & 0x01i32 == 0i32
634 fun &(i: Int32): Int32 is intern
635
636 # Returns the result of a binary OR operation on `self` and `i`
637 #
638 # assert 0x10i32 | 0x01i32 == 0x11i32
639 fun |(i: Int32): Int32 is intern
640
641 # Returns the result of a binary XOR operation on `self` and `i`
642 #
643 # assert 0x101i32 ^ 0x110i32 == 0x11i32
644 fun ^(i: Int32): Int32 is intern
645
646 # Returns the 1's complement of `self`
647 #
648 # assert ~0x2Fi32 == 0xFFFFFFD0i32
649 fun ~: Int32 is intern
650
651 # C function to calculate the length of the `NativeString` to receive `self`
652 private fun to_s_len: Int `{
653 return snprintf(NULL, 0, "%"PRIi32, self);
654 `}
655
656 # C function to convert a nit Int to a NativeString (char*)
657 private fun native_to_s(nstr: NativeString, strlen: Int) `{
658 snprintf(nstr, strlen, "%"PRIi32, self);
659 `}
660
661 # Displayable Int32
662 #
663 # assert 1i32.to_s == "1"
664 # assert (-123i32).to_s == "-123"
665 redef fun to_s do
666 var nslen = to_s_len
667 var ns = new NativeString(nslen + 1)
668 ns[nslen] = 0u8
669 native_to_s(ns, nslen + 1)
670 return ns.to_s_with_length(nslen)
671 end
672 end
673
674 # Native 32-bit unsigned integer.
675 # Same as a C `uint32_t`
676 universal UInt32
677 super Discrete
678 super Numeric
679
680 redef type OTHER: UInt32
681
682 redef fun successor(i) do return self + i.to_u32
683 redef fun predecessor(i) do return self - i.to_u32
684
685 redef fun object_id is intern
686 redef fun hash do return self.to_i
687 redef fun ==(i) is intern
688 redef fun !=(i) is intern
689 redef fun output is intern
690
691 redef fun <=(i) is intern
692 redef fun <(i) is intern
693 redef fun >=(i) is intern
694 redef fun >(i) is intern
695 redef fun +(i) is intern
696
697 # assert -1u32 == 0xFFFFFFFFu32
698 # assert -0u32 == 0x00u32
699 redef fun - is intern
700 redef fun -(i) is intern
701 redef fun *(i) is intern
702 redef fun /(i) is intern
703
704 # Modulo of `self` with `i`.
705 #
706 # Returns the remainder of division of `self` by `i`.
707 #
708 # assert 5u32 % 2u32 == 1u32
709 # assert 10u32 % 2u32 == 0u32
710 fun %(i: UInt32): UInt32 is intern
711
712 redef fun zero do return 0.to_u32
713 redef fun value_of(val) do return val.to_u32
714
715 # `i` bits shift to the left
716 #
717 # assert 5u32 << 1 == 10u32
718 fun <<(i: Int): UInt32 is intern
719
720 # `i` bits shift to the right
721 #
722 # assert 5u32 >> 1 == 2u32
723 fun >>(i: Int): UInt32 is intern
724
725 redef fun to_i is intern
726 redef fun to_f is intern
727 redef fun to_b is intern
728 redef fun to_i8 is intern
729 redef fun to_i16 is intern
730 redef fun to_u16 is intern
731 redef fun to_i32 is intern
732 redef fun to_u32 do return self
733
734 redef fun distance(i) do return (self - i).to_i
735
736 redef fun <=>(other)
737 do
738 if self < other then
739 return -1
740 else if other < self then
741 return 1
742 else
743 return 0
744 end
745 end
746
747 redef fun is_between(c, d)
748 do
749 if self < c or d < self then
750 return false
751 else
752 return true
753 end
754 end
755
756 redef fun max(other)
757 do
758 if self < other then
759 return other
760 else
761 return self
762 end
763 end
764
765 redef fun min(c)
766 do
767 if c < self then
768 return c
769 else
770 return self
771 end
772 end
773
774 # Returns the result of a binary AND operation on `self` and `i`
775 #
776 # assert 0x10u32 & 0x01u32 == 0u32
777 fun &(i: UInt32): UInt32 is intern
778
779 # Returns the result of a binary OR operation on `self` and `i`
780 #
781 # assert 0x10u32 | 0x01u32 == 0x11u32
782 fun |(i: UInt32): UInt32 is intern
783
784 # Returns the result of a binary XOR operation on `self` and `i`
785 #
786 # assert 0x101u32 ^ 0x110u32 == 0x11u32
787 fun ^(i: UInt32): UInt32 is intern
788
789 # Returns the 1's complement of `self`
790 #
791 # assert ~0x2Fu32 == 0xFFFFFFD0u32
792 fun ~: UInt32 is intern
793
794 # C function to calculate the length of the `NativeString` to receive `self`
795 private fun to_s_len: Int `{
796 return snprintf(NULL, 0, "%"PRIu32, self);
797 `}
798
799 # C function to convert a nit Int to a NativeString (char*)
800 private fun native_to_s(nstr: NativeString, strlen: Int) `{
801 snprintf(nstr, strlen, "%"PRIu32, self);
802 `}
803
804 # Displayable UInt32
805 #
806 # assert 1u32.to_s == "1"
807 # assert (-123u32).to_s == "4294967173"
808 redef fun to_s do
809 var nslen = to_s_len
810 var ns = new NativeString(nslen + 1)
811 ns[nslen] = 0u8
812 native_to_s(ns, nslen + 1)
813 return ns.to_s_with_length(nslen)
814 end
815 end