| description | Signed integer arithmetic and modular arithmetic operations. | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| layout |
|
Extended Euclidean algorithm.
Produces .d, the greatest common divisor of .a and .b. Also produces .u and .v such that
.a is an $atom.
.b is an $atom.
.d, the greatest common divisor, is an $atom.
.u, the coefficient of .a, is a signed integer.
.v, the coefficient of .b, is a signed integer.
++ egcd
|= [a=@ b=@]
=+ si
=+ [c=(sun a) d=(sun b)]
=+ [u=[c=(sun 1) d=--0] v=[c=--0 d=(sun 1)]]
|- ^- [d=@ u=@s v=@s]
?: =(--0 c)
[(abs d) d.u d.v]
=+ q=(fra d c)
%= $
c (dif d (pro q c))
d c
u [(dif d.u (pro q c.u)) c.u]
v [(dif d.v (pro q c.v)) c.v]
==> (egcd 11 2)
[d=1 u=--1 v=-5]
Modulo prime.
Container door for modular arithmetic functions.
.a is an $atom
++ fo
^|
|_ a=@Subtraction.
Produces the difference between $atoms .b and .c, with .a as the modular base.
.a is an $atom, and is the sample of +fo.
.b is an $atom.
.c is an $atom.
An $atom.
++ dif
|= [b=@ c=@]
(sit (sub (add a b) (sit c)))> (~(dif fo 6) 1 2)
5
> (~(dif fo 21) 11 45)
8
Exponent.
Produces the power of .c raised to the .b, with .a as the modular base.
.a is an $atom, and is the sample of +fo.
.b is an $atom.
.c is an $atom.
An $atom.
++ exp
|= [b=@ c=@]
?: =(0 b)
1
=+ d=$(b (rsh 0 b))
=+ e=(pro d d)
?:(=(0 (end 0 b)) e (pro c e))> (~(exp fo 5) 8 2)
1
> (~(exp fo 95) 8 2)
66
> (~(exp fo 195) 8 2)
61
> (~(exp fo 995) 8 2)
256
Divide.
Produces the quotient of .b divided by .c, with .a as the modular base.
.a is an $atom, and is the sample of +fo.
.b is an $atom.
.c is an $atom.
An $atom.
++ fra
|= [b=@ c=@]
(pro b (inv c))> (~(fra fo 2) 8 2)
0
> (~(fra fo 3) 8 2)
1
> (~(fra fo 4) 8 2)
0
> (~(fra fo 5) 8 2)
4
Inverse.
Produces an $atom by taking the signed modulus of .a with the coefficient .u; .u is produced by taking the +egcd of .a and .b.
.a is an $atom, and is the sample of +fo.
.b is an $atom.
An $atom.
++ inv
|= b=@
=+ c=(dul:si u:(egcd b a) a)
c> (~(inv fo 11) 2)
6
> (~(inv fo 71) 255)
22
> (~(inv fo 79) 255)
22
> (~(inv fo 78) 255)
67
> (~(inv fo 70) 255)
67
Multiplication.
Produces the multiplication of .b and .c modulo .a.
.a is an $atom, and is the sample of +fo.
.b is an $atom.
.c is an $atom.
An $atom.
++ pro
|= [b=@ c=@]
(sit (mul b c))> (~(pro fo 3) 11 4)
2
> (mod 44 3)
2
Modulus.
Produces the remainder of .b modulo .a.
.a is an $atom, and is the sample of +fo.
.b is an $atom.
An $atom.
++ sit
|= b=@
(mod b a)> (~(sit fo 3) 14)
2
Modular sum.
Produces the remainder of (b + c) mod a.
.a is an $atom, and is the sample of +fo.
.b is an $atom.
.c is an $atom.
An $atom.
++ sum
|= [b=@ c=@]
(sit (add b c))> (~(sum fo 3) 14 3)
2
> (mod 17 3)
2
Signed integer.
Container core for signed integer functions.
++ si
^?
|%The signed-integer type is represented by the @s aura. Positive integers are prepended with a --, and negative integers are prepended with a -. For example, --1 represents positive one, and -1 represents negative one.
ZigZag encoding is used to convert $atoms to signed integers. Positive signed integers correspond to even $atoms of twice their absolute value, and negative signed integers correspond to odd $atoms of twice their absolute value minus one. For example:
> `@`--4
8
> `@s`8
--4
> `@`-4
7
> `@s`7
-4
Absolute value.
Produces the absolute value of signed integer .a.
.a is a signed integer.
An $atom.
++ abs |=(a=@s (add (end 0 a) (rsh 0 a)))> (abs:si -11)
11
> (abs:si --520)
520
Subtraction.
Produces the difference of .a minus .b.
.a is a signed integer.
.b is a signed integer.
A signed integer.
++ dif |= [a=@s b=@s]
(sum a (new !(syn b) (abs b)))> (dif:si --3 -2)
--5
> (dif:si -3 --2)
-5
Modulus.
Produces the remainder of .b modulo .a.
.a is a signed integer.
.b is an $atom.
An $atom.
++ dul |= [a=@s b=@]
=+(c=(old a) ?:(-.c (mod +.c b) (sub b +.c)))> `@s`(dul:si -1 --5)
-5
> `@`--5
10
> `@s`(dul:si -1 10)
-5
> `@s`(dul:si -11 -61)
--55
Divide.
Produces the quotient of .b divided by .c.
.a is a signed integer.
.b is a signed integer.
A signed $atom.
++ fra |= [a=@s b=@s]
(new =(0 (mix (syn a) (syn b))) (div (abs a) (abs b)))> (fra:si -1 -1)
--1
> (fra:si -11 --2)
-5
> (fra:si -0 -1)
--0
Atom to @s.
Produces a signed integer from an $atom .b. The product's sign is determined by the value of flag .a: & will result in a prepending --, and | will result in a prepending -.
.a is a $flag.
.b is an $atom.
A signed integer.
++ new |= [a=? b=@]
`@s`?:(a (mul 2 b) ?:(=(0 b) 0 +((mul 2 (dec b)))))> (new:si | 2)
-2
> (new:si & 2)
--2
> (new:si & -2)
--3
> (new:si & --2)
--4
Sign and absolute value.
Produces a cell composed of a %.y or %.n, depending on whether .a is positive or negative, and the absolute value of .a.
.a is a signed integer.
A cell composed of a $flag and an $atom.
++ old |=(a=@s [(syn a) (abs a)])++ old |=(a=@s [(syn a) (abs a)])> (old:si -2)
[%.n 2]
> (old:si --2)
[%.y 2]
Multiplication.
Produces a signed integer by multiplying .a and .b.
.a is an unsigned integer.
.b is an unsigned integer.
++ pro |= [a=@s b=@s]
(new =(0 (mix (syn a) (syn b))) (mul (abs a) (abs b)))> (pro:si -3 -3)
--9
> (pro:si -3 --3)
-9
Remainder.
Produces a signed integer that is the remainder of .a divided by .b.
.a is a signed integer.
.b is a signed integer.
A signed integer.
++ rem |=([a=@s b=@s] (dif a (pro b (fra a b))))> (rem:si -17 -3)
-2
> (rem:si --17 -3)
--2
> (rem:si -17 --3)
-2
> (rem:si --17 --3)
--2
Addition.
Produces an $atom by adding .a and .b.
.a is a signed integer.
.b is a signed integer.
A signed integer.
++ sum |= [a=@s b=@s]
=+ [c=(old a) d=(old b)]
?: -.c
?: -.d
(new & (add +.c +.d))
?: (gte +.c +.d)
(new & (sub +.c +.d))
(new | (sub +.d +.c))
?: -.d
?: (gte +.c +.d)
(new | (sub +.c +.d))
(new & (sub +.d +.c))
(new | (add +.c +.d))> (sum:si -11 --2)
-9
> (sum:si --2 --2)
--4
@u to @s.
Multiplies the unsigned integer .a by two, producing an $atom.
.a is an unsigned integer.
An $atom.
++ sun |=(a=@u (mul 2 a))> (sun:si 90)
180
> (sun:si --90)
360
> `@u`--90
180
> (sun:si --89)
356
> `@u`--89
178
> (sun:si -89)
354
> `@u`-89
177
Sign test.
Tests whether signed $atom .a is positive or negative. %.y is produced if .a is positive, and %.n is produced if .a is negative.
.a is a signed integer.
A $flag.
++ syn |=(a=@s =(0 (end 0 a)))> (syn:si -2)
%.n
> (syn:si --2)
%.y
Compare.
Compares .a and .b to see which is greater. If .a is greater than .b, --1 is produced. If .b is greater than .a, -1 is produced. If .a and .b are equal, --0 is produced.
.a is a signed integer.
.b is a signed integer.
A signed integer.
++ cmp |= [a=@s b=@s]
^- @s
?: =(a b)
--0
?: (syn a)
?: (syn b)
?: (gth a b)
--1
-1
--1
?: (syn b)
-1
?: (gth a b)
-1
--1> (cmp:si -2 --1)
-1
> (cmp:si -2 --1)
-1
> (cmp:si --2 --1)
--1
> (cmp:si --2 --2)
--0
> (cmp:si --2 --5)
-1