<?xml version="1.0" encoding="UTF-8"?>
<!--
 *
 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2016 - Samuel GOUGEON
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * This file is hereby licensed under the terms of the GNU GPL v2.0,
 * pursuant to article 5.3.4 of the CeCILL v.2.1.
 * This file was originally licensed under the terms of the CeCILL v2.1,
 * and continues to be available under such terms.
 * For more information, see the COPYING file which you should have received
 * along with this program.
 *
 -->
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml"
xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"
xmlns:scilab="http://www.scilab.org" xml:id="bitand" xml:lang="en">
    <refnamediv>
        <refname>bitand</refname>
        <refpurpose>bitwise logical AND between element-wise integers of 2 arrays</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>
            w = bitand(u, v)
        </synopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Parameters</title>
        <variablelist>
            <varlistentry>
                <term>u, v, w</term>
                <listitem>
                    <para>
                        scalars, vectors, matrices or hypermatrices of null or
                        positive integers encoded as decimal or integer numbers
                        of any signed or unsigned <link linkend="inttype">inttype</link>.
                        <warning>Sparse-encoded matrices are not accepted.</warning>
                    </para>
                    <para>
                        If <literal>u</literal> and <literal>v</literal> have
                        the same type and inttype, this one is the working one.
                        Otherwise,
                        <itemizedlist>
                            <listitem>
                                if <literal>u</literal> or <literal>v</literal>
                                is decimal-encoded, the working inttype is 0
                                (real decimal), even if the other operand
                                is int64- or uint64-encoded.
                            </listitem>
                            <listitem>
                                if <literal>u</literal> and <literal>v</literal>
                                are both encoded integers, the working inttype
                                is the widest of both: int8 &lt; uint8 &lt;
                                int16 &lt; uint16 &lt; int32 &lt; uint32 &lt;
                                int64 &lt; uint64.
                            </listitem>
                        </itemizedlist>
                    </para>
                    <para>
                        The result <literal>w</literal> gets the type of the
                        working encoding.
                    </para>
                    <para>
                        <literal>u</literal> and <literal>v</literal> are
                        processed element-wise.
                        <itemizedlist>
                            <listitem>
                                If <literal>u</literal> is a single value (scalar)
                                and <literal>v</literal> is a vector, matrix or
                                hypermatrix, <literal>u</literal> is priorly
                                expanded as <literal>u*ones(v)</literal> in order
                                to operate <literal>u</literal> with every
                                <literal>v</literal> component.
                            </listitem>
                            <listitem>
                                Conversely, <literal>v</literal> is priorly
                                expanded as <literal>v*ones(u)</literal> if it
                                is a single value.
                            </listitem>
                            <listitem>
                                If neither <literal>u</literal> nor <literal>v</literal>
                                are scalars, they must have the same sizes.
                            </listitem>
                        </itemizedlist>
                    </para>
                    <para>
                        The result <literal>w</literal> gets the sizes of
                        <literal>u</literal> or/and <literal>v</literal>
                        arrays.
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Description</title>
        For each pair of components <literal>u(i)</literal> and <literal>v(i)</literal>,
        <literal>bitand(u, v)</literal> computes and returns in <literal>w(i)</literal>
        the bitwise AND conjunction of <literal>u(i)</literal> and <literal>v(i)</literal>
        bits: Bits of <literal>w(i)</literal> set to 1 are met
        in <literal>u(i)</literal> AND in <literal>v(i)</literal>. Otherwise,
        they are set to 0.
        <note>
            With encoded integers, <literal>bitand(u, v)</literal> is equivalent
            to <literal>u &amp; v</literal>. However, <literal>u &amp; v</literal>
            demands that <literal>u</literal> and <literal>v</literal> have
            the same inttype, while <literal>bitand(..)</literal> accepts
            mixed operands.
        </note>
        <note>
            For any decimal integer <literal>u</literal> 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.
        </note>
    </refsection>
    <refsection>
        <title>Examples</title>
        <programlisting role="example"><![CDATA[
bitand(54, 107)
dec2bin([54 107 34]')  // binary representations
     ]]></programlisting>
        <screen><![CDATA[--> bitand(54, 107)
 ans  =
   34.

--> dec2bin([54 107 34]')
 ans  =
!0110110  !
!1101011  !
!0100010  !
]]></screen>
        <para></para>
        <programlisting role="example"><![CDATA[
// 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])
   ]]></programlisting>
        <para></para>
        <programlisting role="example"><![CDATA[
// 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
   ]]></programlisting>
        <screen><![CDATA[--> 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.
]]></screen>
        <para></para>
        <programlisting role="example"><![CDATA[
// 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
   ]]></programlisting>
    </refsection>
    <refsection role="see also">
        <title>See also</title>
        <simplelist type="inline">
            <member>
                <link linkend="and_op">&amp;</link>
            </member>
            <member>
                <link linkend="and">and</link>
            </member>
            <member>
                <link linkend="bitor">bitor</link>
            </member>
            <member>
                <link linkend="dec2bin">dec2bin</link>
            </member>
        </simplelist>
    </refsection>
    <refsection role="history">
        <title>History</title>
        <revhistory>
            <revision>
                <revnumber>6.0</revnumber>
                <revdescription>
                    <itemizedlist>
                        <listitem>
                            Extension to positive signed encoded integers
                        </listitem>
                        <listitem>
                            Extension to new int64 and uint64 inttypes
                        </listitem>
                        <listitem>
                            Operands of mixed types or inttypes are now accepted.
                        </listitem>
                        <listitem>
                            bitand(scalar, array) and bitand(array, scalar) are now supported.
                        </listitem>
                        <listitem>
                            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.
                        </listitem>
                    </itemizedlist>
                </revdescription>
            </revision>
        </revhistory>
    </refsection>
</refentry>
