2c: Bit Arithmetic

    ++bex

    Binary exponent

    Computes the result of 2^a, producing an atom.

    Accepts

    a is an atom.

    Produces

    An atom.

    Source

        ++  bex
          ~/  %bex
          |=  a=@
          ^-  @
          ?:  =(0 a)  1
          (mul 2 $(a (dec a)))
    

    Examples

        > (bex 4)
        16
    
        > (bex (add 19 1))
        1.048.576
    
        > (bex 0)
        1
    

    ++can

    Assemble

    Produces an atom from a list b of length-value pairs p and q, where p is the length in blocks of size a, and q is an atomic value.

    Accepts

    a is a block size (see ++bloq).

    b is a list of length-value pairs, p and q.

    Produces

    An atom.

    Source

        ++  can
          ~/  %can
          |=  [a=bloq b=(list [p=@ q=@])]
          ^-  @
          ?~  b  0
          (add (end a p.i.b q.i.b) (lsh a p.i.b $(b t.b)))
    

    Examples

        > `@ub`21                                         ::  @ub is the binary aura
        0b1.0101
    
        > `@ub`(can 3 ~[[1 21]])
        0b1.0101
    
        > `@ub`(can 3 ~[[1 1]])
        0b1
    
        > `@ub`(can 0 ~[[1 255]])
        0b1
    
        > `@ux`(can 3 [3 0xc1] [1 0xa] ~)                 ::  @ux is the hexadecimal aura
        0xa00.00c1
    
        > `@ux`(can 3 [3 0xc1] [1 0xa] [1 0x23] ~)
        0x23.0a00.00c1
    
        > `@ux`(can 4 [3 0xc1] [1 0xa] [1 0x23] ~)
        0x23.000a.0000.0000.00c1
    
        > `@ux`(can 3 ~[[1 'a'] [2 'bc']])
        0x63.6261
    

    ++cat

    Concatenate

    Concatenates two atoms, b and c, according to block size a, producing an atom.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    c is an atom.

    Produces

    An atom.

    Source

        ++  cat
          ~/  %cat
          |=  [a=bloq b=@ c=@]
          (add (lsh a (met a b) c) b)
    

    Examples

        > `@ub`(cat 3 1 0)                           ::  @ub is the binary aura
        0b1
    
        > `@ub`(cat 0 1 1)
        0b11
    
        > `@ub`(cat 0 2 1)
        0b110
    
        > `@ub`(cat 2 1 1)
        0b1.0001
    
        > `@ub`256
        0b1.0000.0000
    
        > `@ub`255
        0b1111.1111
    
        > `@ub`(cat 3 256 255)
        0b1111.1111.0000.0001.0000.0000
    
        > `@ub`(cat 2 256 255)
        0b1111.1111.0001.0000.0000
    
        > (cat 3 256 255)
        16.711.936
    
        > (cat 2 256 255)
        1.044.736
    

    ++cut

    Slice

    Slices c blocks of size a that are positioned b blocks from the end of d. That slice is produced as an atom.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    c is an atom.

    d is an atom.

    Produces

    An atom.

    Source

        ++  cut
          ~/  %cut
          |=  [a=bloq [b=@u c=@u] d=@]
          (end a c (rsh a b d))
    

    Examples

        > (cut 0 [1 1] 2)
        1
    
        > (cut 0 [2 1] 4)
        1
    
        > `@t`(cut 3 [0 3] 'abcdefgh')
        'abc'
    
        > `@t`(cut 3 [1 3] 'abcdefgh')               ::  @t is the cord aura
        'bcd'
    
        > `@ub`(cut 0 [0 3] 0b1111.0000.1101)        ::  @ub is the binary aura
        0b101
    
        > `@ub`(cut 0 [0 6] 0b1111.0000.1101)
        0b1101
    
        > `@ub`(cut 0 [4 6] 0b1111.0000.1101)
        0b11.0000
    
        > `@ub`(cut 0 [3 6] 0b1111.0000.1101)
        0b10.0001
    

    ++end

    Tail

    Produces an atom by taking the last b blocks of size a from c.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    c is an atom.

    Produces

    An atom.

    Source

        ++  end
          ~/  %end
          |=  [a=bloq b=@u c=@]
          (mod c (bex (mul (bex a) b)))
    

    Examples

        > (end 2 2 255)
        255
    
        > (end 3 1 255)
        255
    
        > (end 3 1 256)
        0
    
        > `@ub`12                                    ::  @ub is the binary aura
        0b1100
    
        > `@ub`(end 0 3 12)
        0b100
    
        > (end 0 3 12)
        4
    
        > `@ub`(end 1 3 12)
        0b1100
    
        > (end 1 3 12)
        12
    
        > `@ux`'abc'                                 ::  @ux is the hexademical aura
        0x63.6261
    
        > `@ux`(end 3 2 'abc')
        0x6261
    
        > `@t`(end 3 2 'abc')                        ::  @t is the cord aura
        'ab'
    

    ++fil

    Fill bloqstream

    Produces an atom by repeating c for b blocks of size a.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    c is an atom.

    Produces

    An atom.

    Source

        ++  fil
          |=  [a=bloq b=@u c=@]
          =+  n=0
          =+  d=c
          |-  ^-  @
          ?:  =(n b)
            (rsh a 1 d)
          $(d (add c (lsh a 1 d)), n +(n))
    

    Examples

        > `@t`(fil 3 5 %a)                                ::  @t is the cord (string) aura
        'aaaaa'
    
        > `@t`(fil 5 10 %ceeb)
        'ceebceebceebceebceebceebceebceebceebceeb'
    
        > `@t`(fil 4 10 %eced)
        'ʇʇʇʇʇʇʇʇʇʇed'
    
        > `@tas`(fil 4 10 %bf)                            ::  @tas is the term aura
        %bfbfbfbfbfbfbfbfbfbf
    
        > `@ub`(fil 2 6 1)                                ::  @ub is the binary aura
        0b1.0001.0001.0001.0001.0001
    

    ++lsh

    Left-shift

    Produces an atom by left-shifting c by b blocks of size a.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    c is an atom.

    Produces

    An atom.

    Source

        ++  lsh
          ~/  %lsh
          |=  [a=bloq b=@u c=@]
          (mul (bex (mul (bex a) b)) c)
    

    Examples

        > `@ub`1                                     ::  @ub is the binary aura
        0b1
    
        > `@ub`(lsh 0 1 1)
        0b10
    
        > (lsh 0 1 1)
        2
    
        > `@ub`255
        0b1111.1111
    
        > `@ub`(lsh 3 1 255)
        0b1111.1111.0000.0000
    
        > (lsh 3 1 255)
        65.280
    

    ++met

    Measure

    Computes the number of blocks of size a in b, producing an atom.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    Source

        ++  met
          ~/  %met
          |=  [a=bloq b=@]
          ^-  @
          =+  c=0
          |-
          ?:  =(0 b)  c
          $(b (rsh a 1 b), c +(c))
    

    Examples

        > (met 0 1)
        1
    
        > (met 0 2)
        2
    
        > (met 3 255)
        1
    
        > (met 3 256)
        2
    
        > (met 3 'abcde')
        5
    

    ++rap

    Assemble non-zero

    Concatenates a list of atoms b using block size a, producing an atom.

    Accepts

    a is a block size (see ++bloq).

    b is a list of atoms.

    Produces

    An atom.

    Source

        ++  rap
          ~/  %rap
          |=  [a=bloq b=(list @)]
          ^-  @
          =+  ~
          ?~  b  0
          (cat a i.b $(b t.b))
    

    Examples

        > `@ub`(rap 2 [1 2 3 4 ~])                   ::  @ub is the binary aura
        0b100.0011.0010.0001
    
        > `@ub`(rap 1 [1 2 3 4 ~])
        0b1.0011.1001
    
        > (rap 0 [0 0 0 ~])
        0
    
        > (rap 0 [1 0 1 ~])
        3
    
        > `@ub`3
        0b11
    
        > (rap 0 [0 1 0 0 1 2 ~])
        11
    
        > (rap 0 [1 1 2 ~])
        11
    
        > `@ub`11
        0b1011
    

    Discussion

    Any element of the value 0 is not included in concatenation.


    ++rep

    Assemble single

    Produces an atom by assembling a list of atoms b using block size a.

    Accepts

    a is a block size (see ++bloq).

    b is a list of atoms.

    Produces

    An atom.

    Source

        ++  rep
          ~/  %rep
          |=  [a=bloq b=(list @)]
          ^-  @
          =+  c=0
          |-
          ?~  b  0
          (add (lsh a c (end a 1 i.b)) $(c +(c), b t.b))
    

    Examples

        > `@ub`(rep 2 [1 2 3 4 ~])                   ::  @ub is the binary aura
        0b100.0011.0010.0001
    
        > (rep 0 [0 0 1 ~])
        4
    
        > (rep 0 [0 0 0 1 ~])
        8
    
        > `@ub`(rep 0 [0 0 0 1 ~])
        0b1000
    
        > `@ub`8
        0b1000
    
        > (rep 0 [0 1 0 0 ~])
        2
    
        > (rep 0 [0 1 0 1 ~])
        10
    
        > (rep 0 [1 0 1 0 1 ~])
        21
    
        > `@ub`21
        0b10.1010
    
        > `@ub`(rep 3 [12 166 8 34 ~])
        0b10.0010.0000.1000.1010.0110.0000.1100
    

    ++rip

    Disassemble

    Produces a list of atoms from the bits of b using block size a.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    Produces

    A list of atoms.

    Source

        ++  rip
          ~/  %rip
          |=  [a=bloq b=@]
          ^-  (list @)
          ?:  =(0 b)  ~
          [(end a 1 b) $(b (rsh a 1 b))]
    

    Examples

        > `@ub`155                                   ::  @ub is the binary aura
        0b1001.1011
    
        > (rip 0 155)
        ~[1 1 0 1 1 0 0 1]
    
        > (rip 2 155)
        ~[11 9]
    
        > (rip 0 11)
        ~[1 1 0 1]
    
        > (rip 1 155)
        ~[3 2 1 2]
    
        > `@ub`256
        0b1.0000.0000
    
        > (rip 0 256)
        ~[0 0 0 0 0 0 0 0 1]
    
        > (rip 2 256)
        ~[0 0 1]
    
        > (rip 3 256)
        ~[0 1]
    

    ++rsh

    Right-shift

    Right-shifts c by b blocks of size a, producing an atom.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    c is an atom.

    Produces

    An atom.

    Source

        ++  rsh
          ~/  %rsh
          |=  [a=bloq b=@u c=@]
          (div c (bex (mul (bex a) b)))
    

    Examples

        > `@ub`145                                   ::  @ub is the binary aura
        0b1001.0001
    
        > `@ub`(rsh 1 1 145)
        0b10.0100
    
        > (rsh 1 1 145)
        36
    
        > `@ub`(rsh 2 1 145)
        0b1001
    
        > (rsh 2 1 145)
        9
    
        > `@ub`10
        0b1010
    
        > `@ub`(rsh 0 1 10)
        0b101
    
        > (rsh 0 1 10)
        5
    
        > `@ux`'abc'
        0x63.6261
    
        > `@t`(rsh 3 1 'abc')
        'bc'
    
        > `@ux`(rsh 3 1 'abc')
        0x6362
    

    ++swp

    Reverse block order

    Switches little-endian to big-endian and vice versa: produces an atom by reversing the block order of b using block size a.

    Accepts

    a is a block size (see ++bloq).

    b is an atom.

    Produces

    An atom

    Source

        ++  swp  |=([a=bloq b=@] (rep a (flop (rip a b))))
    

    Examples

        > `@ub`24                                    ::  @ub is the binary aura
        0b1.1000
    
        > (swp 0 24)
        3
    
        > `@ub`3
        0b11
    
        > (swp 0 0)
        0
    
        > (swp 0 128)
        1
    

    ++xeb

    Binary logarithm

    Computes the base-2 logarithm of a, producing an atom.

    Accepts

    a is an atom.

    Produces

    An atom.

    Source

        ++  xeb
          ~/  %xeb
          |=  a=@
          ^-  @
          (met 0 a)
    

    Examples

        > (xeb 31)
        5
    
        > (xeb 32)
        6
    
        > (xeb 49)
        6
    
        > (xeb 0)
        0
    
        > (xeb 1)
        1
    
        > (xeb 2)
        2
    

    ++fe

    Modulo bloq

    Core that contains arms for bloq and modular integer operations.

    Accepts

    a is a bloq.

    Source

        |_  a=bloq
    

    ++dif:fe

    Produces the difference between two atoms in the modular basis representation.

    Accepts

    a is a bloq.

    b is an atom.

    c is an atom.

    Produces

    A @s

    Source

          ++  dif  |=([b=@ c=@] (sit (sub (add out (sit b)) (sit c))))
    

    Examples

        > (~(dif fe 3) 63 64)
        255
    
        > (~(dif fe 3) 5 10)
        251
    
        > (~(dif fe 3) 0 1)
        255
    
        > (~(dif fe 0) 9 10)
        1
    
        > (~(dif fe 0) 9 11)
        0
    
        > (~(dif fe 0) 9 12)
        1
    
        > (~(dif fe 2) 9 12)
        13
    
        > (~(dif fe 2) 63 64)
        15
    

    ++inv:fe

    Inverse

    Inverts the order of the modular field.

    Accepts

    b is a bloq. (see ++bloq)

    Produces

    An atom.

    Source

          ++  inv  |=(b=@ (sub (dec out) (sit b)))
    

    Examples

        > (~(inv fe 3) 255)
        0
    
        > (~(inv fe 3) 256)
        255
    
        > (~(inv fe 3) 0)
        255
    
        > (~(inv fe 3) 1)
        254
    
        > (~(inv fe 3) 2)
        253
    
        > (~(inv fe 3) 55)
        200
    

    ++net:fe

    Flip endianness

    Reverses bytes within a block.

    Accepts

    b is a bloq. (see ++bloq)

    Produces

    An atom.

    Source

          ++  net  |=  b=@  ^-  @
                   =>  .(b (sit b))
                   ?:  (lte a 3)
                     b
                   =+  c=(dec a)
                   %+  con
                     (lsh c 1 $(a c, b (cut c [0 1] b)))
                   $(a c, b (cut c [1 1] b))
    

    Examples

        > (~(net fe 3) 64)
        64
    
        > (~(net fe 3) 128)
        128
    
        > (~(net fe 3) 255)
        255
    
        > (~(net fe 3) 256)
        0
    
        > (~(net fe 3) 257)
        1
    
        > (~(net fe 3) 500)
        244
    
        > (~(net fe 3) 511)
        255
    
        > (~(net fe 3) 512)
        0
    
        > (~(net fe 3) 513)
        1
    
        > (~(net fe 3) 0)
        0
    
        > (~(net fe 3) 1)
        1
    
        > (~(net fe 0) 1)
        1
    
        > (~(net fe 0) 2)
        0
    
        > (~(net fe 0) 3)
        1
    
        > (~(net fe 6) 1)
        72.057.594.037.927.936
    
        > (~(net fe 6) 2)
        144.115.188.075.855.872
    
        > (~(net fe 6) 3)
        216.172.782.113.783.808
    
        > (~(net fe 6) 4)
        288.230.376.151.711.744
    
        > (~(net fe 6) 5)
        360.287.970.189.639.680
    

    ++out:fe

    Max integer value

    Produces the maximum integer value that the current block can store; 2^a^a.

    Accepts

    a is a bloq.

    Produces

    An atom.

    Source

          ++  out  (bex (bex a))
    

    Examples

        > ~(out fe 0)
        2
    
        > ~(out fe 1)
        4
    
        > ~(out fe 2)
        16
    
        > ~(out fe 3)
        256
    
        > ~(out fe 4)
        65.536
    
        > ~(out fe 10)
        \/179.769.313.486.231.590.772.930.519.078.902.473.361.797.697.894.230.657.273\/
          .430.081.157.732.675.805.500.963.132.708.477.322.407.536.021.120.113.879.87
          1.393.357.658.789.768.814.416.622.492.847.430.639.474.124.377.767.893.424.8
          65.485.276.302.219.601.246.094.119.453.082.952.085.005.768.838.150.682.342.
          462.881.473.913.110.540.827.237.163.350.510.684.586.298.239.947.245.938.479
          .716.304.835.356.329.624.224.137.216
        \/                                                                           \/
    

    ++rol:fe

    Roll left

    Rolls d to the left by c b-sized blocks.

    Accepts

    a is a bloq.

    b is a bloq.

    c is an atom.

    d is an atom.

    Produces

    An atom.

    Source

          ++  rol  |=  [b=bloq c=@ d=@]  ^-  @
                   =+  e=(sit d)
                   =+  f=(bex (sub a b))
                   =+  g=(mod c f)
                   (sit (con (lsh b g e) (rsh b (sub f g) e)))
    

    Examples

        > `@ux`(~(rol fe 6) 4 3 0xabac.dedf.1213)
        0x1213.0000.abac.dedf
    
        > `@ux`(~(rol fe 6) 4 2 0xabac.dedf.1213)
        0xdedf.1213.0000.abac
    
        > `@t`(~(rol fe 5) 3 1 'dfgh')
        'hdfg'
    
        > `@t`(~(rol fe 5) 3 2 'dfgh')
        'ghdf'
    
        > `@t`(~(rol fe 5) 3 0 'dfgh')
        'dfgh'
    

    ++ror:fe

    Roll right

    Rolls d to the right by c b-sized blocks.

    Accepts

    a is a bloq.

    b is a bloq.

    c is an atom.

    d is an atom.

    Produces

    An atom.

    Source

          ++  ror  |=  [b=bloq c=@ d=@]  ^-  @
                   =+  e=(sit d)
                   =+  f=(bex (sub a b))
                   =+  g=(mod c f)
                   (sit (con (rsh b g e) (lsh b (sub f g) e)))
    

    Examples

        > `@ux`(~(ror fe 6) 4 1 0xabac.dedf.1213)
        0x1213.0000.abac.dedf
    
        > `@ux`(~(ror fe 6) 3 5 0xabac.dedf.1213)
        0xacde.df12.1300.00ab
    
        > `@ux`(~(ror fe 6) 3 3 0xabac.dedf.1213)
        0xdf12.1300.00ab.acde
    
        > `@t`(~(rol fe 5) 3 0 'hijk')
        'hijk'
    
        > `@t`(~(rol fe 5) 3 1 'hijk')
        'khij'
    
        > `@t`(~(rol fe 5) 3 2 'hijk')
        'jkhi'
    

    ++sit:fe

    Enforce modulo

    Produces an atom in the current modular block representation.

    Accepts

    a is a bloq.

    b is an atom.

    Produces

    An atom.

    Source

          ++  sit  |=(b=@ (end a 1 b))
    

    Examples

        > (~(sit fe 3) 255)
        255
    
        > (~(sit fe 3) 256)
        0
    
        > (~(sit fe 3) 257)
        1
    
        > (~(sit fe 2) 257)
        1
    
        > (~(sit fe 2) 10.000)
        0
    
        > (~(sit fe 2) 100)
        4
    
        > (~(sit fe 2) 19)
        3
    
        > (~(sit fe 2) 17)
        1
    
        > (~(sit fe 0) 17)
        1
    
        > (~(sit fe 0) 0)
        0
    
        > (~(sit fe 0) 1)
        1
    

    ++sum:fe

    Sum

    Sums two numbers in this modular field.

    Accepts

    a is a bloq.

    b is an atom.

    c is an atom.

    Produces

    An atom.

    Source

          ++  sum  |=([b=@ c=@] (sit (add b c)))
    

    Examples

        > (~(sum fe 3) 10 250)
        4
    
        > (~(sum fe 0) 0 1)
        1
    
        > (~(sum fe 0) 0 2)
        0
    
        > (~(sum fe 2) 14 2)
        0
    
        > (~(sum fe 2) 14 3)
        1
    
        > (~(sum fe 4) 10.000 256)
        10.256
    
        > (~(sum fe 4) 10.000 100.000)
        44.464