bitand bitwise logical AND between element-wise integers of 2 arrays

## Syntax

                w = bitand(u, v)

## Parameters

u, v, w

  scalars, vectors, matrices or hypermatrices of null or positive integers encoded as decimal or integer numbers of any signed or unsigned inttype.

  Sparse-encoded matrices are not accepted.

  If `u` and `v` have the same type and inttype, this one is the working one. Otherwise,

  - if `u` or `v` is decimal-encoded, the working inttype is 0 (real decimal), even if the other operand is int64- or uint64-encoded.
  - if `u` and `v` are both encoded integers, the working inttype is the widest of both: int8 < uint8 < int16 < uint16 < int32 < uint32 < int64 < uint64.

  The result `w` gets the type of the working encoding.

  `u` and `v` are processed element-wise.

  - If `u` is a single value (scalar) and `v` is a vector, matrix or hypermatrix, `u` is priorly expanded as `u*ones(v)` in order to operate `u` with every `v` component.
  - Conversely, `v` is priorly expanded as `v*ones(u)` if it is a single value.
  - If neither `u` nor `v` are scalars, they must have the same sizes.

  The result `w` gets the sizes of `u` or/and `v` arrays.

## Description

For each pair of components `u(i)` and `v(i)`, `bitand(u, v)` computes and returns in `w(i)` the bitwise AND conjunction of `u(i)` and `v(i)` bits: Bits of `w(i)` set to 1 are met in `u(i)` AND in `v(i)`. Otherwise, they are set to 0.
With encoded integers, `bitand(u, v)` is equivalent to `u & v`. However, `u & v` demands that `u` and `v` have the same inttype, while `bitand(..)` accepts mixed operands.
For any decimal integer `u` greater than 2^52, only its bits from log2(u) down to log2(u)-52 are encoded and can be actually taken into account. Lower bits are not stored and are then ignored.

## Examples

    bitand(54, 107)
    dec2bin([54 107 34]')  // binary representations

    --> bitand(54, 107)
     ans  =
       34.

    --> dec2bin([54 107 34]')
     ans  =
    !0110110  !
    !1101011  !
    !0100010  !

    // Between 2 simple rows with zeros and ones
    u = [0 1 0 1];
    v = [0 0 1 1];
    bitand(u, v)    // [0 0 0 1] expected

    // Encoded integers such as int8 are accepted:
    u = int8([0 1 0 1]);
    v = int8([0 0 1 1]);
    bitand(u, v)

    // Operands of mixed types are accepted.
    // The type of the result is decimal if a decimal operand is involved,
    // or the widest integer one otherwise:
    u = [0 1 0 1];
    v = [0 0 1 1];
    z = bitand(u, int64(v));         type(z)      // 1 : decimal representation
    z = bitand(uint8(u), int8(v));   typeof(z)    // uint8
    z = bitand(uint8(u), int32(v));  typeof(z)    // int32

    // Usage with 2 matrices
    u = [  0  1   0   1
          54 107 107 54 ];
    v = [  0  0   1   1
          107 54 34  34 ];
    bitand(u, v)     //  [ 0 0 0 1 ;  34 34 34 34 ]   expected

    // Usage with a distributed scalar:
    bitand([1 2 4 8 9 10 12], 8)  // == bitand([1 2 4 8 9 10 12], [8 8 8 8 8 8 8])
    bitand(4, [1 2 4 8 9 10 12])  // == bitand([4 4 4 4 4 4 4], [1 2 4 8 9 10 12])

    // With encoded integers, bitand(u,v) and u & v are equivalent:
    u = int8([2 3 10]);
    v = int8(13);
    [bitand(u, v) ; u &amp; v]
    // ... but "&" demands operands having the same type:
    u &amp; 13    // mismatching int8- | decimal- encodings

    --> u = int8([2 3 10]);
    --> v = int8(13);
    --> [bitand(u, v) ; u &amp; v]
     ans  =
      0  1  8
      0  1  8
    --> u &amp; 13
    Undefined operation for the given operands.
    check or define function %i_h_s for overloading.

    // Examples with big decimal integers:

    u = sum(2 .^(600+[0 3 9 20 45]))        // ~ 1.46D+194
    bitand(u, 2^601) == 0    // True: The bit #601 is set to 0 in u
    v = 2 .^[603 610];
    bitand(u, v) == 2^603    // True: the bit #603 is the only one common to u and v
    bitand(u, 2^646-1) == 0  // True: 2^646-1 has theoretically bits #1 to #645 set to 1
                             // BUT -1/(2^646) is <<< %eps and is then ignored:
                             // 2^646 is actually used instead of 2^646-1.
                             // Now, 2^646 has bits #1 to #645set to 0. So the result.
    bitand(u, 2^646-2^599)==u  // %T: 2^646-2^599 has actually bits #599 to #645 set to 1
    //
    n = fix(log2(u))       // == 645: Index of the heaviest bit of u
    bitand(u, u+2^(n-53)) == u   // True: Addressing bits below the lightest one has no effect
    bitand(u, u-2^(n-53)) == u   // True: idem

## See also

- &
- and
- bitor
- dec2bin

## History

6.0

- Extension to positive signed encoded integers
- Extension to new int64 and uint64 inttypes
- Operands of mixed types or inttypes are now accepted.
- bitand(scalar, array) and bitand(array, scalar) are now supported.
- Extension to decimal numbers greater than 2^32 and even than 2^52, up to 1.80D+308 (== number_properties("huge")), for the 52 heaviest encoded bits of their unsigned mantissa.