on b93c19b help sign in
857 lines 10 kB history raw
1+++
2title = "3a: Modular and Signed Ints"
3weight = 21
4template = "doc.html"
5+++
6# 3a: modular and signed ints
8### `++egcd`
10Extended Euclidean algorithm
12Produces `d`, the
13[greatest common divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor)
14of `a` and `b`. Also produces `u` and `v` such that `au + bv = GCD(a, b)`.
16#### Accepts
18`a` is an atom.
20`b` is an atom.
22#### Produces
24`d`, the greatest common divisor, is an atom.
26`u`, the coefficient of `a`, is a signed integer.
28`v`, the coefficient of `b`, is a signed integer.
30#### Source
32```
33 ++ egcd
34 |= [a=@ b=@]
35 =+ si
36 =+ [c=(sun a) d=(sun b)]
37 =+ [u=[c=(sun 1) d=--0] v=[c=--0 d=(sun 1)]]
38 |- ^- [d=@ u=@s v=@s]
39 ?: =(--0 c)
40 [(abs d) d.u d.v]
41 =+ q=(fra d c)
42 %= $
43 c (dif d (pro q c))
44 d c
45 u [(dif d.u (pro q c.u)) c.u]
46 v [(dif d.v (pro q c.v)) c.v]
47 ==
48```
50#### Examples
52```
53 > (egcd 11 2)
54 [d=1 u=--1 v=-5]
55```
57---
58### `++fo`
60Modulo prime
62Container core for modular arithmetic functions.
64#### Source
66```
67 ++ fo
68 ^?
69 |_ a=@
70```
72### `++dif:fo`
74Subtraction
76Produces the difference between atoms `b` and `c`, with `a` as the modular base.
78#### Accepts
80`a` is an atom.
82`b` is an atom.
84`c` is an atom.
86#### Produces
88An atom.
90#### Source
92```
93 ++ dif
94 |= [b=@ c=@]
95 (sit (sub (add a b) (sit c)))
96```
98#### Examples
100```
101 > (~(dif fo 6) 1 2)
102 5
104 > (~(dif fo 21) 11 45)
105 8
106```
108### `++exp:fo`
110Exponent
112Produces the power of `b` raised to the `c`, with `a` as the modular base.
114#### Accepts
116`a` is an atom.
118`b` is an atom.
120`c` is an atom.
122#### Produces
124An atom.
126#### Source
128```
129 ++ exp
130 |= [b=@ c=@]
131 ?: =(0 b)
132 1
133 =+ d=$(b (rsh 0 1 b))
134 =+ e=(pro d d)
135 ?:(=(0 (end 0 1 b)) e (pro c e))
136```
138#### Examples
140```
141 > (~(exp fo 5) 8 2)
142 1
144 > (~(exp fo 95) 8 2)
145 66
147 > (~(exp fo 195) 8 2)
148 61
150 > (~(exp fo 995) 8 2)
151 256
152```
154---
155### `++fra:fo`
157Divide
159Produces the quotient of `b` divided by `c`, with `a` as the modular base.
161#### Accepts
163`a` is an atom.
165`b` is an atom.
167`c` is an atom.
169#### Produces
171An atom.
173#### Accepts
175`a` is an atom.
177`b` is an atom.
179#### Source
181```
182 ++ fra
183 |= [b=@ c=@]
184 (pro b (inv c))
185```
187#### Examples
189```
190 > (~(fra fo 2) 8 2)
191 0
193 > (~(fra fo 3) 8 2)
194 1
196 > (~(fra fo 4) 8 2)
197 0
199 > (~(fra fo 5) 8 2)
200 4
201```
203---
204### `++inv:fo`
206Inverse
208Produces an atom by taking the signed modulus of `a` with the coefficient `u`;
209`u` is produced by taking the `++egcd` of `a` and `b`.
211#### Accepts
213`a` is an atom.
215`b` is an atom.
217#### Produces
219An atom.
221#### Source
223```
224 ++ inv
225 |= b=@
226 =+ c=(dul:si u:(egcd b a) a)
227 c
228```
230#### Examples
232```
233 > (~(inv fo 11) 2)
234 6
236 > (~(inv fo 71) 255)
237 22
239 > (~(inv fo 79) 255)
240 22
242 > (~(inv fo 78) 255)
243 67
245 > (~(inv fo 70) 255)
246 67
247```
249---
250### `++pro:fo`
252Multiplication
254Produces the multiplication of `b` and `c` modulo `a`.
256#### Accepts
258`a` is an atom.
260`b` is an atom.
262`c` is an atom.
264#### Produces
266An atom.
268#### Source
270```
271 ++ pro
272 |= [b=@ c=@]
273 (sit (mul b c))
274```
276#### Examples
278```
279 > (~(pro fo 3) 11 4)
280 2
282 > (mod 44 3)
283 2
284```
286---
287### `++sit:fo`
289Modulus
291Produces the remainder of `b` modulo `a`.
293#### Accepts
295`a` is an atom.
297`b` is an atom.
299#### Produces
301An atom.
303#### Source
305```
306 ++ sit
307 |= b=@
308 (mod b a)
309```
311#### Examples
313```
314 > (~(sit fo 3) 14)
315 2
316```
318---
319### `++sum:fo`
321Modular sum
323Produces the remainder of `(b + c) mod a`.
325#### Accepts
327`a` is an atom.
329`b` is an atom.
331`c` is an atom.
333#### Produces
335An atom.
337#### Source
339```
340 ++ sum
341 |= [b=@ c=@]
342 (sit (add b c))
343 --
344```
346#### Examples
348```
349 > (~(sum fo 3) 14 3)
350 2
352 > (mod 17 3)
353 2
354```
356---
357### `++si`
359Signed integer
361Container core for signed integer functions.
363#### Source
365```
366 ++ si
367 ^?
368 |%
369```
371#### Discussion
373The signed-integer type is represented by the `@s` aura. Positive integers are
374represented with a two prepending `-`s, and negative integers are represented
375with two; `--1` and `-1`, respectively.
377Positive signed integers correspond to odd atoms of twice their absolute value,
378and negative signed integers correspond to atoms of twice their absolute value
379minus one. For example:
381```
382 > `@`--4
383 8
384 > `@s`8
385 --4
387 > `@`-4
388 7
389 > `@s`7
390 -4
391```
393---
394### `++abs:si`
396Absolute value
398Produces the absolute value of signed integer `a`.
400#### Accepts
402`a` is a signed integer.
404#### Produces
406An atom.
408### Source
410```
411 ++ abs |=(a=@s (add (end 0 1 a) (rsh 0 1 a)))
412```
414#### Examples
416```
417 > (abs:si -11)
418 11
420 > (abs:si --520)
421 520
422```
424---
425### `++dif:si`
427Subtraction
429Produces the difference of `a` minus `b`.
431#### Accepts
433`a` is a signed integer.
435`b` is a signed integer.
437#### Produces
439A signed integer.
441#### Source
443```
444 ++ dif |= [a=@s b=@s]
445 (sum a (new !(syn b) (abs b)))
446```
448#### Examples
450```
451 > (dif:si --3 -2)
452 --5
454 > (dif:si -3 --2)
455 -5
456```
458---
459### `++dul:si`
461Modulus
463Produces the remainder of `b` modulo `a`.
465#### Examples
467`a` is a signed integer.
469`b` is an atom.
471#### Produces
473An atom.
475#### Source
477```
478 ++ dul |= [a=@s b=@]
479 =+(c=(old a) ?:(-.c (mod +.c b) (sub b +.c)))
480```
482#### Examples
484```
485 > `@s`(dul:si -1 --5)
486 -5
488 > `@`--5
489 10
490 > `@s`(dul:si -1 10)
491 -5
493 > `@s`(dul:si -11 -61)
494 --55
495```
497---
498### `++fra:si`
500Divide
502Produces the quotient of `b` divided by `c`.
504#### Accepts
506`a` is a signed integer.
508`b` is a signed integer.
510#### Produces
512A signed atom.
514#### Source
516```
517 ++ fra |= [a=@s b=@s]
518 (new =(0 (mix (syn a) (syn b))) (div (abs a) (abs b)))
519```
521#### Examples
523```
524 > (fra:si -1 -1)
525 --1
527 > (fra:si -11 --2)
528 -5
530 > (fra:si -0 -1)
531 --0
532```
534---
535### `++new:si`
537Atom to @s
539Produces a signed integer from an atom `b`. The product's sign is determined
540by the value of flag `a`: `&` will result in a prepending `--`, and `|` will
541result in a prepending `-`.
543#### Accepts
545`a` is a flag.
547`b` is an atom.
549#### Produces
551A signed integer.
553#### Source
555```
556 ++ new |= [a=? b=@]
557 `@s`?:(a (mul 2 b) ?:(=(0 b) 0 +((mul 2 (dec b)))))
558```
560#### Examples
562```
563 > (new:si | 2)
564 -2
566 > (new:si & 2)
567 --2
569 > (new:si & -2)
570 --3
572 > (new:si & --2)
573 --4
574```
576---
577### `++old:si`
579Sign and absolute value
581Produces a cell composed of a `%.y` or `%.n`, depending on whether `a` is
582positive or negative, and the absolute value of `a`.
584#### Accepts
586`a` is a signed integer.
588#### Produces
590A cell composed of a `term` and an atom.
592#### Source
594```
595 ++ old |=(a=@s [(syn a) (abs a)])
596```
598#### Examples
600```
601 > (old:si -2)
602 [%.n 2]
604 > (old:si --2)
605 [%.y 2]
606```
608---
609### `++pro:si`
611Multiplication
613Produces a signed integer by multiplying `a` and `b`.
615#### Accepts
617`a` is an unsigned integer.
619`b` is an unsigned integer.
621#### Source
623```
624 ++ pro |= [a=@s b=@s]
625 (new =(0 (mix (syn a) (syn b))) (mul (abs a) (abs b)))
626```
628#### Examples
630```
631 > (pro:si -3 -3)
632 --9
634 > (pro:si -3 --3)
635 -9
636```
638---
639### `++rem:si`
641Remainder
643Produces a signed integer that is the remainder of `a` divided by `b`.
645#### Accepts
647`a` is a signed integer.
649`b` is a signed integer.
651#### Produces
653A signed integer.
655#### Source
657```
658 ++ rem |=([a=@s b=@s] (dif a (pro b (fra a b))))
659```
661#### Examples
663```
664 > (rem:si -17 -3)
665 -2
667 > (rem:si --17 -3)
668 --2
670 > (rem:si -17 --3)
671 -2
673 > (rem:si --17 --3)
674 --2
675```
678---
679### `++sum:si`
681Addition
683Produces an atom by adding `a` and `b`.
685#### Accepts
687`a` is a signed integer.
689`b` is a signed integer.
691#### Produces
693A signed integer.
695#### Source
697```
698 ++ sum |= [a=@s b=@s]
699 =+ [c=(old a) d=(old b)]
700 ?: -.c
701 ?: -.d
702 (new & (add +.c +.d))
703 ?: (gte +.c +.d)
704 (new & (sub +.c +.d))
705 (new | (sub +.d +.c))
706 ?: -.d
707 ?: (gte +.c +.d)
708 (new | (sub +.c +.d))
709 (new & (sub +.d +.c))
710 (new | (add +.c +.d))
711```
713#### Examples
715```
716 > (sum:si -11 --2)
717 -9
719 > (sum:si --2 --2)
720 --4
721```
723---
724### `++sun:si`
726@u to @s
728Multiplies the unsigned integer `a` by two, producing an atom.
730#### Accepts
732`a` is an unsigned integer.
734#### Produces
736An atom.
738#### Source
740```
741 ++ sun |=(a=@u (mul 2 a))
742```
744#### Examples
746```
747 > (sun:si 90)
748 180
750 > (sun:si --90)
751 360
752 > `@u`--90
753 180
755 > (sun:si --89)
756 356
757 > `@u`--89
758 178
760 > (sun:si -89)
761 354
762 > `@u`-89
763 177
764```
766---
767### `++syn:si`
769Sign test
771Tests whether signed atom `a` is positive or negative. `%.y` is produced if `a`
772is positive, and `%.n` is produced if `a` is negative.
774#### Accepts
776`a` is a signed integer.
778#### Produces
780An `term`.
782#### Source
784```
785 ++ syn |=(a=@s =(0 (end 0 1 a)))
786```
788#### Examples
790```
791 > (syn:si -2)
792 %.n
794 > (syn:si --2)
795 %.y
796```
798---
799### `++cmp:si`
801Compare
803Compares `a` and `b` to see which is greater. If `a` is greater than `b`, `--1`
804is produced. If `b` is greater than `a`, `-1` is produced. If `a` and `b` are
805equal, `--0` is produced.
807#### Accepts
809`a` is a signed integer.
811`b` is a signed integer.
813#### Produces
815A signed integer.
817#### Source
819```
820 ++ cmp |= [a=@s b=@s]
821 ^- @s
822 ?: =(a b)
823 --0
824 ?: (syn a)
825 ?: (syn b)
826 ?: (gth a b)
827 --1
828 -1
829 --1
830 ?: (syn b)
831 -1
832 ?: (gth a b)
833 -1
834 --1
835 --
836```
838#### Examples
840```
841 > (cmp:si -2 --1)
842 -1
844 > (cmp:si -2 --1)
845 -1
847 > (cmp:si --2 --1)
848 --1
850 > (cmp:si --2 --2)
851 --0
853 > (cmp:si --2 --5)
854 -1
855```
857---