⍝   S i g n e d   B i n a r y   A r i t h m e t i c

    ← .()           ⍝ binary digit binding, eg:  5 → 1.0.1

      -()           ⍝ neg (unary minus)
    → ∧()           ⍝ pow
    ← *() /() %()   ⍝ mul div mod (rem)
    ← +() -()       ⍝ add sub

⍝ Pattern matching variables:

      i j :: 0 1
      p q ::
    r s t ::

⍝ trim
            0.j = j
⍝ carry
         1 +  1 =  1.0
        -1 + -1 = -1.0

       p.( 1.j) = (p+1).j
       p.(-1.j) = (p-1).j
         p.(-j) = (p-1).j
         (-p).j = -p.j
⍝ neg
            --q = q
⍝ add
          p + 0 = p
          0 + q = q

      p.i +   j =     p.(i+j)
        i + q.j =     q.(i+j)
      p.i + q.j = (p+q).(i+j)

        -p +  q = q-p
         p + -q = p-q
        -p + -q = -(p+q)
⍝ mul
        p *   0 = 0
        p *   1 = p
        p * q.j = (p*q).0 + p*j

        -p *  q = -(p*q)
         p * -q = -(p*q)
        -p * -q =   p*q
⍝ pow
        p ∧   0 = 1
        p ∧   1 = p
        p ∧ q.j = p∧q * p∧q * p∧j
⍝ sub
          p - 0 =  p
          p - p =  0
          0 - q = -q

      p.i -   j =    p .(i-j)
        i - q.j =   -q .(j-i)
      p.i - q.j = (p-q).(i-j)

       -p - q   = -(p+q)
⍝ div
        -p / -q =  (div A1; p; q; p; q)
        -p /  q = -(div A1; p; q; p; q)
         p / -q = -(div A1; p; q; p; q)
         p /  q =  (div A1; p; q; p; q)

     div q; r =  q                                  ⍝ extract quotient

⍝ mod
        -p % -q = -(mod A1; p; q; p; q)
        -p %  q = -(mod A1; p; q; p; q)
         p % -q =  (mod A1; p; q; p; q)
         p %  q =  (mod A1; p; q; p; q)

     mod q; r = r                                   ⍝ extract remainder

⍝ "long division" algorithm. See →notes.Long_division←

    A1; p; q; r.i; s.j     = A1; p; q; r; s         ⍝ A: left align divisor
    A1; p; q; r  ;   j     = A2; p; q; |; r         ⍝ reset shift mechanism
    A1; p; q;   i; s       = A2; p; q; |; i

    A2; p; q; s; r.i       = A2; p; q.0; s.<; r     ⍝ shift divisor & count
    A2; p; q; s;   i       = B1; p; q;   s;   0     ⍝ s-shifted divisor q

    B1; p; q; s; r         = B2; p; q; s; r; p-q    ⍝ subtract

    B2; p; q.j; s.<; r; -t = B1; p;   q; s; r.0     ⍝ shift right & repeat
    B2; p; q.j; s.<; r;  t = B1; t;   q; s; r.1
    B2; p; q;   |;   r; -t =     r.0; p             ⍝ finished
    B2; p; q;   |;   r;  t =     r.1; t

⍝ (low precedence) auxiliary functions

    ← ;()                           ⍝ division state item separator
    div() mod()                     ⍝ division result separation
    ← =()   ≡()                     ⍝ reduction equivalence/trace

⍝ Test cases:
⍝
⍝    1.1+1.1                      ->  1.1.0             ⍝ 3 + 3 → 6
⍝   -1.1-1.1                      -> -1.1.0
⍝    1.1+-1.1.1                   -> -1.0.0
⍝   0-1-1-1-1                     -> -1.0.0
⍝   -1.1*-1.1                     ->  1.0.0.1
⍝   -1.1∧ 1.1                     -> -1.1.0.1.1         ⍝ ¯3 * 3 → ¯27
⍝    1.1∧-1                       ->  1.1∧-1            ⍝ no fractions
⍝   1.1.1/1.1                     ->  1.0
⍝   1.1.1/-1.1                    -> -1.0
⍝   -1.1.1/1.1                    -> -1.0
⍝   -1.1.1/-1.1                   ->  1.0
⍝   1.1.1%1.1                     ->  1                 ⍝ 7 |⍨ 3 → 1
⍝   1.1.1%-1.1                    ->  1
⍝   -1.1.1%1.1                    -> -1
⍝   -1.1.1%-1.1                   -> -1
⍝   1.1.1.1.1.0.1.0.0.0/1         ->  1.1.1.1.1.0.1.0.0.0
⍝   1.1.1.1.1.1.1.1.1.1/1.1.1.1.1 ->  1.0.0.0.0.1
⍝   
⍝   Back to: Contents