* Bugs 12013 & 14655 fixed: bitset() upgraded 77/20677/6
Samuel GOUGEON [Fri, 4 Jan 2019 23:44:11 +0000 (00:44 +0100)]
  * http://bugzilla.scilab.org/12013
  * http://bugzilla.scilab.org/14655

  bitset() rewritten accordingly with bitget()
  bitset page rewritten. In PDF: http://bugzilla.scilab.org/attachment.cgi?id=4877

  In addition to the patches and new features (see CHANGES and history):
   - the old implementation of hypermatrices was still used
   - argins tests are extended.
   - unit tests were minimalist. They are now almost exhaustive.

Change-Id: I3f09e4f81eb53f50faaf49d02fbca88702512586

scilab/CHANGES.md
scilab/modules/elementary_functions/help/en_US/bitwise/bitset.xml
scilab/modules/elementary_functions/help/ja_JP/bitwise/bitset.xml [deleted file]
scilab/modules/elementary_functions/help/ru_RU/bitwise/bitset.xml
scilab/modules/elementary_functions/macros/bitset.sci
scilab/modules/elementary_functions/tests/unit_tests/bitset.dia.ref [deleted file]
scilab/modules/elementary_functions/tests/unit_tests/bitset.tst
scilab/modules/helptools/data/pages/homepage-en_US.html

index 3b861cb..7da24d0 100644 (file)
@@ -104,6 +104,12 @@ Feature changes and additions
   - For decimal numbers: bits with indices > 52 can now be retrieved (up to `log2(number_properties("huge"))` = 1024).
   - For decimal numbers `x > 2^52`, queried bits below `%eps` (indices < log2(x)-52) now return `Nan` instead of 0.
   - Several bits can now be retrieved from each component of an input array.
+* `bitset` is upgraded:
+  - It now accepts positive Signed encoded integers.
+  - It now supports the new uint64 and int64 types of encoded integers.
+  - For decimal numbers: bits with indices > 32 can now be set (up to #1024).
+  - Several bits can now be set for each input component.
+  - Distributive scalar inputs are now accepted.
 * `bitstring` function added.
 * `edit` now accepts a line number as text (like "23").
 * `profileEnable`, `profileDisable`, `profileGetInfo` could be used to instrument functions and gather execution information within Scilab.
@@ -251,6 +257,7 @@ Bug Fixes
 ---------
 
 ### Bugs fixed in 6.1.0:
+<<<<<<< HEAD
 * [#2694](https://bugzilla.scilab.org/2694): `bitget` did not accept positive integers of types int8, int16 or int32.
 * [#5824](https://bugzilla.scilab.org/5824): The `datafit` algorithm was not documented.
 * [#6070](https://bugzilla.scilab.org/6070): How to make multiscaled plots was not documented.
@@ -461,3 +468,20 @@ Bug Fixes
 * [#16321](https://bugzilla.scilab.org/16321): There were typo errors in the documentation.
 * [#16323](https://bugzilla.scilab.org/16323): `conj(sparse(x))` was complex when x is real.
 * [#16325](https://bugzilla.scilab.org/16325): `mgetl` could not read single line data which is greater than ~260,000 characters.
+=======
+* [#2694](http://bugzilla.scilab.org/show_bug.cgi?id=2694): `bitget` did not accept positive integers of types int8, int16 or int32.
+* [#8784](http://bugzilla.scilab.org/show_bug.cgi?id=8784): Automatic self-adjusting blocks `SCALE_CSCOPE` & `SCALE_CMSCOPE` in Xcos.
+* [#12013](http://bugzilla.scilab.org/show_bug.cgi?id=12013): `bitset` did not work for numbers greater than 2^32-1.
+* [#14655](http://bugzilla.scilab.org/show_bug.cgi?id=14655): `bitset` worked only element-wise, without accepting mixed scalar and array inputs.
+* [#14604](http://bugzilla.scilab.org/show_bug.cgi?id=14604): `emptystr()` is 40x slower with 6.0.0 wrt 5.5.2
+* [#14605](http://bugzilla.scilab.org/show_bug.cgi?id=14605): fixed - `bench_run` was too strict about the specification of tests names.
+* [#14812](http://bugzilla.scilab.org/show_bug.cgi?id=14812): Minor typos in messages.
+* [#14863](http://bugzilla.scilab.org/show_bug.cgi?id=14863): In Xcos, the default ending time was unhandily high (100000), reduced it to 30.
+* [#14982](http://bugzilla.scilab.org/show_bug.cgi?id=14982): `msprintf` segmentation fault was caught due to wrong size
+* [#15269](http://bugzilla.scilab.org/show_bug.cgi?id=15269): `xgetech` was poor and stiff compared to any combination of `gca()` properties `.axes_bounds`, `.data_bounds`, `.log_flags`, and `.margins`. It is removed.
+* [#15271](http://bugzilla.scilab.org/show_bug.cgi?id=15271): `bitget` needed to be upgraded.
+* [#15425](http://bugzilla.scilab.org/show_bug.cgi?id=15425): The Kronecker product `a.*.b` failed when `a` or `b` or both are hypermatrices, with one or both being polynomials or rationals.
+* [#15523](http://bugzilla.scilab.org/show_bug.cgi?id=15523): `%ODEOPTIONS(1)=2` didn't work with solvers 'rk' and 'rkf' 
+* [#15577](http://bugzilla.scilab.org/show_bug.cgi?id=15577): `edit` did not accept a line number as text, as with `edit linspace 21`.
+
+>>>>>>> a82a833092d... * Bugs 12013 & 14655 fixed: bitset() upgraded
index 28c00db..c7fe46f 100644 (file)
@@ -1,10 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
- *
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2011 - DIGITEO - Michael Baudin
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2019 - Samuel GOUGEON
  *
  * 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.
  * 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="bitset" xml:lang="en">
+<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="bitset" xml:lang="en">
     <refnamediv>
         <refname>bitset</refname>
-        <refpurpose>set bit at specified position</refpurpose>
+        <refpurpose>Sets bits of given indices in some integers</refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Syntax</title>
         <synopsis>
-            y = bitset(x, pos)
-            y = bitset(x, pos, v)
+            y = bitset(x, bitInd)
+            y = bitset(x, bitInd, bitVal)
         </synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Parameters</title>
         <variablelist>
             <varlistentry>
-                <term>x :</term>
+                <term>x</term>
                 <listitem>
                     <para>
-                        a <literal>m</literal>-by-<literal>n</literal> matrix of doubles
-                        or a <literal>m1</literal>-by-<literal>m2</literal>-by-...-by-<literal>mm</literal> hypermatrix of doubles
-                        or a <literal>m</literal>-by-<literal>n</literal> matrix of unsigned integers (<literal>uint8</literal>, <literal>uint16</literal> or <literal>uint32</literal>).
-                        Must contain positive integer values.
+                        positive decimal or encoded integers (all inttypes supported), whose bits
+                        must be set. Supported sizes: scalar, vector, matrix, hypermatrix.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>pos :</term>
+                <term>bitInd</term>
                 <listitem>
                     <para>
-                        a <literal>m</literal>-by-<literal>n</literal> matrix of doubles
-                        or a <literal>m1</literal>-by-<literal>m2</literal>-by-...-by-<literal>mm</literal> hypermatrix of doubles
-                        or a <literal>m</literal>-by-<literal>n</literal> matrix of unsigned integers (<literal>uint8</literal>, <literal>uint16</literal> or <literal>uint32</literal>).
-                        Must contain positive integer values.
-                        The input <literal>pos</literal> must be in the range 1,2,...,<literal>bitmax</literal>
-                        where <literal>bitmax</literal> is the maximum number of bits in <varname>x</varname>.
+                        Indices of bits to be set: Array of positive decimal or encoded integers
+                        (all inttypes supported), whose values are in the interval
+                        <literal>[1 bitmax]</literal> where <varname>bitmax</varname> is the
+                        maximal index of bits for the type of <varname>x</varname>.
+                        The bit #1 is the lightest one (2<superscript>0</superscript>).
+            <table style="padding:0px">
+                <tr><th>typeof(x)</th><th>bitmax</th><td>..</td><th>typeof(x)</th><th>bitmax</th></tr>
+                <tr align="center"><td>int8  </td><td>7</td> <td>  </td><td>uint8</td><td>8</td></tr>
+                <tr align="center"><td>int16 </td><td>15</td><td>  </td><td>uint16</td><td>16</td></tr>
+                <tr align="center"><td>int32 </td><td>31</td><td>  </td><td>uint32</td><td>32</td></tr>
+                <tr align="center"><td>int64 </td><td>63</td><td>  </td><td>uint16</td><td>64</td></tr>
+                <tr align="center"><td>decimal</td><td>1024</td><td>  </td><td></td><td></td></tr>
+            </table>
+                    </para>
+                    <para>
+                        <itemizedlist>
+                            <listitem>
+                                <para>
+                                If the size of <varname>bitInd</varname> matches <varname>x</varname>'s
+                                one, the processing is performed element-wise: For every
+                                index i in x, the bit #bitInd(i) is set in x(i).
+                                </para>
+                            </listitem>
+                            <listitem>
+                                <para>
+                                If <varname>x</varname> has N dimensions and the N first sizes of
+                                <varname>bitInd</varname> match <varname>x</varname> ones, and
+                                <varname>bitInd</varname> has N+1 dimensions, then for each
+                                <literal>x(i1,i2,..iN)</literal>, all its bits
+                                <literal>#bitInd(i1,i2,..iN, :)</literal> are set.
+                                </para>
+                            </listitem>
+                            <listitem>
+                                <para>
+                                Otherwise: <varname>bitInd</varname> must be a vector of length&lt;=
+                                <varname>bitmax</varname>. Then, all the bits listed in
+                                <varname>bitInd</varname> are set in all <varname>x</varname> components.
+                                </para>
+                            </listitem>
+                        </itemizedlist>
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>v :</term>
+                <term>bitVal</term>
                 <listitem>
                     <para>
-                        a <literal>m</literal>-by-<literal>n</literal> matrix of doubles
-                        or a <literal>m1</literal>-by-<literal>m2</literal>-by-...-by-<literal>mm</literal> hypermatrix of doubles
-                        or a <literal>m</literal>-by-<literal>n</literal> matrix of unsigned integers (<literal>uint8</literal>, <literal>uint16</literal> or <literal>uint32</literal>). Default <varname>v</varname><literal>=1</literal>.
-                        Must contain positive integer values.
+                        Array of values 0 or 1 as decimal or encoded integers (all inttypes supported)
+                        : values to which respective bits must be set. <varname>bitVal</varname>
+                        has either the size of <varname>bitInd</varname>, or it is scalar
+                        (then the same value is used for all bits).
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>y :</term>
+                <term>y</term>
                 <listitem>
                     <para>
-                        a <literal>m</literal>-by-<literal>n</literal> matrix of doubles
-                        or a <literal>m1</literal>-by-<literal>m2</literal>-by-...-by-<literal>mm</literal> hypermatrix of doubles
-                        or a <literal>m</literal>-by-<literal>n</literal> matrix of unsigned integers.
+                        Processed <varname>x</varname>, with the same size and data type
+                        (and integer type) as <varname>x</varname>.
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Description</title>
         <para>
-            Set the bit at specified position <varname>pos</varname>.
+            Sets the bits of <varname>x</varname> indicated by <varname>bitInd</varname>,
+            either to 1 or to the given values <varname>bitVal</varname>.
         </para>
     </refsection>
     <refsection>
         <title>Examples</title>
+        <para>
+         Setting one or several bits in a scalar:
+        </para>
+        <programlisting role="example"><![CDATA[
+n = int8(20);
+ns = bitset(n, [1 3 6]) // setting bits #1 #3 #6 (to 1 by default)
+bitget([n ns], 1:7)     // bits content before / after setting
+
+ns = bitset(n, [1 3 6], [1 0 1]) // to explicit bits values
+bitget([n ns], 1:7)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = int8(20);
+--> ns = bitset(n, [1 3 6]) // setting bits #1 #3 #6 (to 1 by default)
+ ns  =
+  53
+
+--> bitget([n ns], 1:7)     // bits content before / after setting
+ ans  =
+  0  0  1  0  1  0  0
+  1  0  1  0  1  1  0
+
+--> ns = bitset(n, [1 3 6], [1 0 1]) // to explicit bits values
+ ns  =
+  49
+
+--> bitget([n ns], 1:7)
+ ans  =
+  0  0  1  0  1  0  0
+  1  0  0  0  1  1  0
+]]></screen>
+        <para>
+        Setting the same bits to the same respective values for all input elements:
+        </para>
+        <programlisting role="example"><![CDATA[
+n = uint16([28  59; 23  19])
+ns = bitset(n, [3 5], [1 0])
+bitget(n, 1:8)
+bitget(ns,1:8)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = uint16([28  59; 23  19])
+ n  =
+  28  59
+  23  19
+
+--> ns = bitset(n, [3 5], [1 0])
+ ns  =
+  12  47
+   7   7
+
+--> bitget(n, 1:8)
+ ans  =
+  0  0  1  1  1  0  0  0
+  1  1  1  0  1  0  0  0
+  1  1  0  1  1  1  0  0
+  1  1  0  0  1  0  0  0
+
+--> bitget(ns,1:8)
+ ans  =
+  0  0  1  1  0  0  0  0
+  1  1  1  0  0  0  0  0
+  1  1  1  1  0  1  0  0
+  1  1  1  0  0  0  0  0
+]]></screen>
+        <para>
+        Setting a single bit of each element of an array, at a bit index depending
+        on the element, in an element-wise way:
+        </para>
+        <programlisting role="example"><![CDATA[
+n = uint16([94 78 ; 6 19])
+ns = bitset(n, [2 4 ; 3 5], 0)            // To the same bit value 0
+ns2 = bitset(n, [1 3 ; 2 4], [1 0 ; 0 1]) // To respective bits values
+// Analysis:
+bitget(ns, 1:8)  // #[2 3 4 5] set to 0
+bitget(n, 1:8)   // input
+bitget(ns2, 1:8) // #[1 2 3 4] set to [1 0 0 1]
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = uint16([94 78 ; 6 19])
+ n  =
+  94  78
+   6  19
+
+--> ns = bitset(n, [2 4 ; 3 5], 0)            // To the same bit value 0
+ ns  =
+  92  70
+   2   3
+
+--> ns2 = bitset(n, [1 3 ; 2 4], [1 0 ; 0 1]) // To respective bits values
+ ns2  =
+  95  74
+   4  27
+
+--> // Analysis:
+--> bitget(ns, 1:8)    // #[2 3 4 5] set to 0
+ ans  =
+  0  0  1  1  1  0  1  0
+  0  1  0  0  0  0  0  0
+  0  1  1  0  0  0  1  0
+  1  1  0  0  0  0  0  0
+
+--> bitget(n, 1:8)     // input
+ ans  =
+  0  1  1  1  1  0  1  0
+  0  1  1  0  0  0  0  0
+  0  1  1  1  0  0  1  0
+  1  1  0  0  1  0  0  0
+
+--> bitget(ns2, 1:8)    // #[1 2 3 4] set to [1 0 0 1]
+ ans  =
+  1  1  1  1  1  0  1  0
+  0  0  1  0  0  0  0  0
+  0  1  0  1  0  0  1  0
+  1  1  0  1  1  0  0  0
+]]></screen>
+        <para>
+        Setting several bits in each input element, in an element-wise way:
+        </para>
+        <programlisting role="example"><![CDATA[
+// Bits set to 1:
+n = int64([6 49 71]);
+bitInd = cat(3, [1 3 5], [2 4 6])
+ns = bitset(n, bitInd)
+bitget(n, 1:8)
+bitget(ns, 1:8)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = int64([6 49 71]);
+--> bitInd = cat(3, [1 3 5], [2 4 6])
+ bitInd  =
+(:,:,1)
+   1.   3.   5.
+(:,:,2)
+   2.   4.   6.
+
+--> ns = bitset(n, bitInd)
+ ns  =
+  7  61  119
+
+--> bitget(n, 1:8)
+ ans  =
+  0  1  1  0  0  0  0  0
+  1  0  0  0  1  1  0  0
+  1  1  1  0  0  0  1  0
+
+--> bitget(ns, 1:8)
+ ans  =
+  1  1  1  0  0  0  0  0
+  1  0  1  1  1  1  0  0
+  1  1  1  0  1  1  1  0
+]]></screen>
+        <para/>
+        <programlisting role="example"><![CDATA[
+// Bits set to respective values:
+n = uint64([6 49 71]);
+bitInd = cat(3, [1 3 5], [2 4 6])
+bitVal = cat(3, [1 1 1], [0 0 0])
+n
+ns = bitset(n, bitInd, bitVal)
+bitget(n, 1:8)
+bitget(ns, 1:8)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> bitInd = cat(3, [1 3 5], [2 4 6])
+ bitInd  =
+(:,:,1)
+   1.   3.   5.
+(:,:,2)
+   2.   4.   6.
+
+--> bitVal = cat(3, [1 1 1], [0 0 0])
+ bitVal  =
+(:,:,1)
+   1.   1.   1.
+(:,:,2)
+   0.   0.   0.
+
+--> n
+ n  =
+  6  49  71
+
+--> ns = bitset(n, bitInd, bitVal)
+ ns  =
+  5  53  87
+
+--> bitget(n, 1:8)
+ ans  =
+  0  1  1  0  0  0  0  0
+  1  0  0  0  1  1  0  0
+  1  1  1  0  0  0  1  0
+
+--> bitget(ns, 1:8)
+ ans  =
+  1  0  1  0  0  0  0  0
+  1  0  1  0  1  1  0  0
+  1  1  1  0  1  0  1  0
+]]></screen>
+        <para>
+        Setting bits in decimal numbers, even for big numbers:
+        </para>
         <programlisting role="example"><![CDATA[
-// 9 is (01001)_2
-// We set the 5th bit to 1, which gives
-//      (11001)_2 producing 25
-bitset(uint8(9), 5)
-expected = 25
-
-// Set the 5th bit of 25 to 0.
-bitset(uint8(25), 5, 0)
-expected = 9
-
-// The input can be a positive double
-bitset(25, 5, 0)
-expected = 9
+n = [0 1.2345e20];
+showBits =     [1 10 40 50 60 61 62 63 64 65 66];
+ns = bitset(n, [  10 40       61    63 64 65   ], ..
+               [   1  0        1     1  0  1   ])
+[bitget(n, showBits); showBits ; bitget(ns, showBits)] // [before ; bits # ; after]
+// bits at #<(65|66 - 53) are unknown
    ]]></programlisting>
+   <screen><![CDATA[
+--> ns = bitset(n, [  10 40       61    63 64 65   ], ..
+  >                [   1  0        1     1  0  1   ])
+ ns  =
+   2.421D+19   1.373D+20
+
+--> [bitget(n, showBits); showBits ; bitget(ns, showBits)] // [before ; bits # ; after]
+ ans  =
+   0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.
+   Nan   Nan   1.    1.    0.    1.    1.    0.    1.    0.    1.
+   1.    10.   40.   50.   60.   61.   62.   63.   64.   65.   66.
+   Nan   Nan   0.    0.    0.    1.    0.    1.    0.    1.    0.
+   Nan   Nan   0.    1.    0.    1.    1.    1.    0.    1.    1.
+
+--> // bits at #<(65|66 - 53) are unknown
+]]></screen>
+    </refsection>
+    <refsection role="see also">
+        <title>See Also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="bitget">bitget</link>
+            </member>
+            <member>
+                <link linkend="or_op">|, ||</link>
+            </member>
+            <member>
+                <link linkend="and_op">&amp;, &amp;&amp;</link>
+            </member>
+            <member>
+                <link linkend="or">or</link>
+            </member>
+            <member>
+                <link linkend="and">and</link>
+            </member>
+            <member>
+                <link linkend="bin2dec">bin2dec</link>
+            </member>
+            <member>
+                <link linkend="dec2bin">dec2bin</link>
+            </member>
+        </simplelist>
+    </refsection>
+    <refsection role="history">
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>5.0</revnumber>
+                <revdescription>
+                    Function introduced
+                </revdescription>
+            </revision>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revdescription>
+                    <itemizedlist>
+                        <listitem>
+                            64-bit integers now supported.
+                        </listitem>
+                        <listitem>
+                            Support to positive signed integers added.
+                        </listitem>
+                        <listitem>
+                            With decimal numbers, bits #53 to #1024 can now be properly set.
+                        </listitem>
+                        <listitem>
+                            For each input element, several bits can now be set at the same time.
+                        </listitem>
+                        <listitem>
+                            Input arguments can now mixed arrays and scalars, instead of mandatory
+                            element-wise arrays.
+                        </listitem>
+                    </itemizedlist>
+                </revdescription>
+            </revision>
+        </revhistory>
     </refsection>
 </refentry>
diff --git a/scilab/modules/elementary_functions/help/ja_JP/bitwise/bitset.xml b/scilab/modules/elementary_functions/help/ja_JP/bitwise/bitset.xml
deleted file mode 100644 (file)
index 07b44d5..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- *
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2011 - DIGITEO - Michael Baudin
- *
- * 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="bitset" xml:lang="ja">
-
-    <refnamediv>
-
-        <refname>bitset</refname>
-
-        <refpurpose>指定した位置のビットを設定</refpurpose>
-
-    </refnamediv>
-
-    <refsynopsisdiv>
-
-        <title>呼び出し手順</title>
-
-        <synopsis>
-
-            y = bitset(x, pos)
-
-            y = bitset(x, pos, v)
-
-        </synopsis>
-
-    </refsynopsisdiv>
-
-    <refsection>
-
-        <title>引数</title>
-
-        <variablelist>
-
-            <varlistentry>
-
-                <term>x :</term>
-
-                <listitem>
-
-                    <para>
-
-                        <literal>m</literal>行<literal>n</literal>列の行列(double)
-
-                        または<literal>m1</literal> x <literal>m2</literal> x ... x <literal>mm</literal>
-
-                        ハイパー行列(double)
-
-                        または符合なし整数(<literal>uint8</literal>, <literal>uint16</literal>または
-
-                        <literal>uint32</literal>)の<literal>m</literal>行<literal>n</literal>列行列.
-
-                        値は正の整数値である必要があります.
-
-                    </para>
-
-                </listitem>
-
-            </varlistentry>
-
-            <varlistentry>
-
-                <term>pos :</term>
-
-                <listitem>
-
-                    <para>
-
-                        <literal>m</literal>行<literal>n</literal>列の行列(double)
-
-                        または<literal>m1</literal> x <literal>m2</literal> x ... x <literal>mm</literal>
-
-                        ハイパー行列(double)
-
-                        または符合なし整数(<literal>uint8</literal>, <literal>uint16</literal>または
-
-                        <literal>uint32</literal>)の<literal>m</literal>行<literal>n</literal>列行列.
-
-                        値は正の整数値である必要があります.
-
-                        入力 <literal>pos</literal> は 1,2,...,<literal>bitmax</literal>の範囲とする
-
-                        必要があります.ただし,<literal>bitmax</literal>は<varname>x</varname>
-
-                        の最大ビット数です.
-
-                    </para>
-
-                </listitem>
-
-            </varlistentry>
-
-            <varlistentry>
-
-                <term>v :</term>
-
-                <listitem>
-
-                    <para>
-
-                        <literal>m</literal>行<literal>n</literal>列の行列(double)
-
-                        または<literal>m1</literal> x <literal>m2</literal> x ... x <literal>mm</literal>
-
-                        ハイパー行列(double)
-
-                        または符合なし整数(<literal>uint8</literal>, <literal>uint16</literal>または
-
-                        <literal>uint32</literal>)の<literal>m</literal>行<literal>n</literal>列行列.
-
-                        デフォルトで<varname>v</varname><literal>=1</literal>です.
-
-                        値は正の整数値である必要があります.
-
-                    </para>
-
-                </listitem>
-
-            </varlistentry>
-
-            <varlistentry>
-
-                <term>y :</term>
-
-                <listitem>
-
-                    <para>
-
-                        <literal>m</literal>行<literal>n</literal>列の行列(double)
-
-                        または<literal>m1</literal> x <literal>m2</literal> x ... x <literal>mm</literal>
-
-                        ハイパー行列(double)
-
-                        または<literal>m</literal>行<literal>n</literal>列の符号無し整数の行列.
-
-                    </para>
-
-                </listitem>
-
-            </varlistentry>
-
-        </variablelist>
-
-    </refsection>
-
-    <refsection>
-
-        <title>説明</title>
-
-        <para>
-
-            指定した位置<varname>pos</varname>のビットを設定します.
-
-        </para>
-
-    </refsection>
-
-    <refsection>
-
-        <title>例</title>
-
-        <programlisting role="example"><![CDATA[
-// 9 は (01001)_2 です
-// 5番目のビットを1に設定し,
-//      (11001)_2 ( = 25)とします
-bitset(uint8(9), 5)
-expected = 25
-
-// 25の5番目のビットを0に設定
-bitset(uint8(25), 5, 0)
-expected = 9
-
-// 入力は正のdoubleにすることができます
-bitset(25, 5, 0)
-expected = 9
-   ]]></programlisting>
-
-    </refsection>
-
-</refentry>
-
index ee01a38..b16b2a1 100644 (file)
@@ -1,10 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
- *
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2011 - DIGITEO - Michael Baudin
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2019 - Samuel GOUGEON
  *
  * 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.
  * 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="bitset" xml:lang="ru">
+<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="bitset" xml:lang="ru">
     <refnamediv>
         <refname>bitset</refname>
-        <refpurpose>установка бита в определённой позиции</refpurpose>
+        <refpurpose>устанавливает в целых числах биты по указанным индексам</refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Синтаксис</title>
         <synopsis>
-            y = bitset(x, pos)
-            y = bitset(x, pos, v)
+            y = bitset(x, bitInd)
+            y = bitset(x, bitInd, bitVal)
         </synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Параметры</title>
         <variablelist>
             <varlistentry>
-                <term>x :</term>
+                <term>x</term>
                 <listitem>
                     <para>
-                        матрица чисел двойной точности (<literal>double</literal>) размером <literal>m</literal> на <literal>n</literal>
-                        или гиперматрица чисел двойной точности размером <literal>m1</literal> на <literal>m2</literal> на ... на <literal>mm</literal>
-                        или матрица беззнаковых целых чисел (<literal>uint8</literal>, <literal>uint16</literal> или <literal>uint32</literal>) размером <literal>m</literal> на <literal>n</literal>. Должна содержать положительные целые значения.
+                        положительные десятичные или кодированные целые числа (поддерживаются все типы целых чисел),
+                        в которых нужно установить биты. Поддерживаемые размеры: скаляр, вектор, матрица, гиперматрица.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>pos :</term>
+                <term>bitInd</term>
                 <listitem>
                     <para>
-                        матрица чисел двойной точности (<literal>double</literal>) размером <literal>m</literal> на <literal>n</literal>
-                        или гиперматрица чисел двойной точности размером <literal>m1</literal> на <literal>m2</literal> на ... на <literal>mm</literal>
-                        или матрица беззнаковых целых чисел (<literal>uint8</literal>, <literal>uint16</literal> или <literal>uint32</literal>) размером <literal>m</literal> на <literal>n</literal>. Должна содержать положительные целые значения.
-                        Входная <varname>pos</varname> должна быть в диапазоне 1,2,...,<literal>bitmax</literal>
-                        где <literal>bitmax</literal> - максимальное количество битов в <varname>x</varname>.
+                        Индексы битов, которые должны быть установлены: массив положительных десятичных или кодированных
+                        целых чисел (поддерживаются все типы целых чисел), чьи значения находятся в интервале
+                        <literal>[1 bitmax]</literal>, где <varname>bitmax</varname> - это максимальный индекс битов для
+                        типа <varname>x</varname>.
+                        Бит №1 - самый младший (2<superscript>0</superscript>).
+            <table style="padding:0px">
+                <tr><th>typeof(x)</th><th>bitmax</th><td>..</td><th>typeof(x)</th><th>bitmax</th></tr>
+                <tr align="center"><td>int8  </td><td>7</td> <td>  </td><td>uint8</td><td>8</td></tr>
+                <tr align="center"><td>int16 </td><td>15</td><td>  </td><td>uint16</td><td>16</td></tr>
+                <tr align="center"><td>int32 </td><td>31</td><td>  </td><td>uint32</td><td>32</td></tr>
+                <tr align="center"><td>int64 </td><td>63</td><td>  </td><td>uint16</td><td>64</td></tr>
+                <tr align="center"><td>decimal</td><td>1024</td><td>  </td><td></td><td></td></tr>
+            </table>
+                    </para>
+                    <para>
+                        <itemizedlist>
+                            <listitem>
+                                <para>
+                                  Если размер <varname>bitInd</varname> совпадает с размером <varname>x</varname>, то
+                                  выполняется поэлементная обработка: для каждого индекса <literal>i</literal> в
+                                  <varname>x</varname> бит №<literal>bitInd(i)</literal> устанавливается в <literal>x(i)</literal>.
+                                </para>
+                            </listitem>
+                            <listitem>
+                                <para>
+                                Если <varname>x</varname> имеет <literal>N</literal> размерностей и первые <literal>N</literal>
+                                размерностей <varname>bitInd</varname> совпадают с размерностями <varname>x</varname>, и
+                                <varname>bitInd</varname> имеет <literal>N+1</literal> размерностей, то для каждого
+                                <literal>x(i1,i2,..iN)</literal> будут установлены все его биты
+                                <literal>№bitInd(i1,i2,..iN, :)</literal>.
+                                </para>
+                            </listitem>
+                            <listitem>
+                                <para>
+                                В противном случае: <varname>bitInd</varname> должен быть вектором длиной&lt;=
+                                <varname>bitmax</varname>. Тогда все биты, указанные в <varname>bitInd</varname>, устанавливаются
+                                во всех элементах <varname>x</varname>.
+                                </para>
+                            </listitem>
+                        </itemizedlist>
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>v :</term>
+                <term>bitVal</term>
                 <listitem>
                     <para>
-                        матрица чисел двойной точности (<literal>double</literal>) размером <literal>m</literal> на <literal>n</literal>
-                        или гиперматрица чисел двойной точности размером <literal>m1</literal> на <literal>m2</literal> на ... на <literal>mm</literal>
-                        или матрица беззнаковых целых чисел (<literal>uint8</literal>, <literal>uint16</literal> или <literal>uint32</literal>) размером <literal>m</literal> на <literal>n</literal>. По умолчанию <varname>v</varname><literal>=1</literal>. Должна содержать положительные целые значения.
+                        Массив значений 0 или 1 в виде десятичных или кодированных целых чисел (поддерживаются
+                        все типы целых чисел): значения в которые соответствующие биты должны быть установлены.
+                        <varname>bitVal</varname> либо имеет размер <varname>bitInd</varname>, либо является скаляром
+                        (тогда одно и то же значение используется для всех битов).
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>y :</term>
+                <term>y</term>
                 <listitem>
                     <para>
-                        матрица чисел двойной точности размером <literal>m</literal> на <literal>n</literal>
-                        или гиперматрица чисел двойной точности размером <literal>m1</literal> на <literal>m2</literal> на ... на <literal>mm</literal>
-                        или матрица беззнаковых целых чисел размером <literal>m</literal> на <literal>n</literal>.
+                        Обработанный <varname>x</varname> с тем же размером и типом данных (и типом целых чисел), что и
+                        <varname>x</varname>.
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Описание</title>
         <para>
-            Установка бита в определённой позиции <varname>pos</varname>.
+           Устанавливает биты <varname>x</varname>, указанные с помощью <varname>bitInd</varname> либо в 1, либо в
+           указанные значения <varname>bitVal</varname>.
         </para>
     </refsection>
     <refsection>
         <title>Примеры</title>
+        <para>
+           Установка одного или нескольких битов в скаляре:
+        </para>
+        <programlisting role="example"><![CDATA[
+n = int8(20);
+ns = bitset(n, [1 3 6]) // Установка битов №1 №3 №6 (в 1, по умолчанию)
+bitget([n ns], 1:7)     // содержимое битов до/после установки
+
+ns = bitset(n, [1 3 6], [1 0 1]) // в явно указанные значения битов
+bitget([n ns], 1:7)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = int8(20);
+--> ns = bitset(n, [1 3 6]) // Установка битов №1 №3 №6 (в 1, по умолчанию)
+ ns  =
+  53
+
+--> bitget([n ns], 1:7)     // содержимое битов до/после установки
+ ans  =
+  0  0  1  0  1  0  0
+  1  0  1  0  1  1  0
+
+--> ns = bitset(n, [1 3 6], [1 0 1]) // в явно указанные значения битов
+ ns  =
+  49
+
+--> bitget([n ns], 1:7)
+ ans  =
+  0  0  1  0  1  0  0
+  1  0  0  0  1  1  0
+]]></screen>
+        <para>
+        Установка одних и тех же битов в одно и тоже значение во всех входных элементах:
+        </para>
+        <programlisting role="example"><![CDATA[
+n = uint16([28  59; 23  19])
+ns = bitset(n, [3 5], [1 0])
+bitget(n, 1:8)
+bitget(ns,1:8)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = uint16([28  59; 23  19])
+ n  =
+  28  59
+  23  19
+
+--> ns = bitset(n, [3 5], [1 0])
+ ns  =
+  12  47
+   7   7
+
+--> bitget(n, 1:8)
+ ans  =
+  0  0  1  1  1  0  0  0
+  1  1  1  0  1  0  0  0
+  1  1  0  1  1  1  0  0
+  1  1  0  0  1  0  0  0
+
+--> bitget(ns,1:8)
+ ans  =
+  0  0  1  1  0  0  0  0
+  1  1  1  0  0  0  0  0
+  1  1  1  1  0  1  0  0
+  1  1  1  0  0  0  0  0
+]]></screen>
+        <para>
+               Установка отдельного бита в каждом элементе массива по индексу бита в зависимости от элемента, поэлементно:
+        </para>
+        <programlisting role="example"><![CDATA[
+n = uint16([94 78 ; 6 19])
+ns = bitset(n, [2 4 ; 3 5], 0)            // в одно и то же значение бита 0
+ns2 = bitset(n, [1 3 ; 2 4], [1 0 ; 0 1]) // в соответствующие значения битов
+// Анализ:
+bitget(ns, 1:8)  // #[2 3 4 5] устанавливаются в 0
+bitget(n, 1:8)   // вход
+bitget(ns2, 1:8) // #[1 2 3 4] устанавливаются в [1 0 0 1]
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = uint16([94 78 ; 6 19])
+ n  =
+  94  78
+   6  19
+
+--> ns = bitset(n, [2 4 ; 3 5], 0)            // в одно и то же значение бита 0
+ ns  =
+  92  70
+   2   3
+
+--> ns2 = bitset(n, [1 3 ; 2 4], [1 0 ; 0 1]) // в соответствующие значения битов
+ ns2  =
+  95  74
+   4  27
+
+--> // Анализ:
+--> bitget(ns, 1:8)    // #[2 3 4 5] устанавливаются в 0
+ ans  =
+  0  0  1  1  1  0  1  0
+  0  1  0  0  0  0  0  0
+  0  1  1  0  0  0  1  0
+  1  1  0  0  0  0  0  0
+
+--> bitget(n, 1:8)     // вход
+ ans  =
+  0  1  1  1  1  0  1  0
+  0  1  1  0  0  0  0  0
+  0  1  1  1  0  0  1  0
+  1  1  0  0  1  0  0  0
+
+--> bitget(ns2, 1:8)    // #[1 2 3 4] устанавливаются в [1 0 0 1]
+ ans  =
+  1  1  1  1  1  0  1  0
+  0  0  1  0  0  0  0  0
+  0  1  0  1  0  0  1  0
+  1  1  0  1  1  0  0  0
+]]></screen>
+        <para>
+           Установка нескольких битов в каждом входном элементе, поэлементно:
+        </para>
+        <programlisting role="example"><![CDATA[
+// Биты устанавливаются в 1:
+n = int64([6 49 71]);
+bitInd = cat(3, [1 3 5], [2 4 6])
+ns = bitset(n, bitInd)
+bitget(n, 1:8)
+bitget(ns, 1:8)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> n = int64([6 49 71]);
+--> bitInd = cat(3, [1 3 5], [2 4 6])
+ bitInd  =
+(:,:,1)
+   1.   3.   5.
+(:,:,2)
+   2.   4.   6.
+
+--> ns = bitset(n, bitInd)
+ ns  =
+  7  61  119
+
+--> bitget(n, 1:8)
+ ans  =
+  0  1  1  0  0  0  0  0
+  1  0  0  0  1  1  0  0
+  1  1  1  0  0  0  1  0
+
+--> bitget(ns, 1:8)
+ ans  =
+  1  1  1  0  0  0  0  0
+  1  0  1  1  1  1  0  0
+  1  1  1  0  1  1  1  0
+]]></screen>
+        <para/>
+        <programlisting role="example"><![CDATA[
+// Биты устанавливаются в соответствующие значения:
+n = uint64([6 49 71]);
+bitInd = cat(3, [1 3 5], [2 4 6])
+bitVal = cat(3, [1 1 1], [0 0 0])
+n
+ns = bitset(n, bitInd, bitVal)
+bitget(n, 1:8)
+bitget(ns, 1:8)
+   ]]></programlisting>
+   <screen><![CDATA[
+--> bitInd = cat(3, [1 3 5], [2 4 6])
+ bitInd  =
+(:,:,1)
+   1.   3.   5.
+(:,:,2)
+   2.   4.   6.
+
+--> bitVal = cat(3, [1 1 1], [0 0 0])
+ bitVal  =
+(:,:,1)
+   1.   1.   1.
+(:,:,2)
+   0.   0.   0.
+
+--> n
+ n  =
+  6  49  71
+
+--> ns = bitset(n, bitInd, bitVal)
+ ns  =
+  5  53  87
+
+--> bitget(n, 1:8)
+ ans  =
+  0  1  1  0  0  0  0  0
+  1  0  0  0  1  1  0  0
+  1  1  1  0  0  0  1  0
+
+--> bitget(ns, 1:8)
+ ans  =
+  1  0  1  0  0  0  0  0
+  1  0  1  0  1  1  0  0
+  1  1  1  0  1  0  1  0
+]]></screen>
+        <para>
+           Установка битов в десятичных числах, даже для больших чисел:
+        </para>
         <programlisting role="example"><![CDATA[
-// 9 соответствует (01001)_2
-// Установим 5-й бит в 1, что приводит к
-//      (11001)_2, соответствующее 25
-bitset(uint8(9), 5)
-expected = 25
-
-// Установим 5-й бит числа 25 в 0.
-bitset(uint8(25), 5, 0)
-expected = 9
-
-// Входное значение может быть положительным числом типа double
-bitset(25, 5, 0)
-expected = 9
+n = [0 1.2345e20];
+showBits =     [1 10 40 50 60 61 62 63 64 65 66];
+ns = bitset(n, [  10 40       61    63 64 65   ], ..
+               [   1  0        1     1  0  1   ])
+[bitget(n, showBits); showBits ; bitget(ns, showBits)] // [перед ; № бита ; после]
+// биты в №<(65|66 - 53) являются неизвестными
    ]]></programlisting>
+   <screen><![CDATA[
+--> ns = bitset(n, [  10 40       61    63 64 65   ], ..
+  >                [   1  0        1     1  0  1   ])
+ ns  =
+   2.421D+19   1.373D+20
+
+--> [bitget(n, showBits); showBits ; bitget(ns, showBits)] // [перед ; № бита ; после]
+ ans  =
+   0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.
+   Nan   Nan   1.    1.    0.    1.    1.    0.    1.    0.    1.
+   1.    10.   40.   50.   60.   61.   62.   63.   64.   65.   66.
+   Nan   Nan   0.    0.    0.    1.    0.    1.    0.    1.    0.
+   Nan   Nan   0.    1.    0.    1.    1.    1.    0.    1.    1.
+
+--> // биты в №<(65|66 - 53) являются неизвестными
+]]></screen>
+    </refsection>
+    <refsection role="see also">
+        <title>Смотрите также</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="bitget">bitget</link>
+            </member>
+            <member>
+                <link linkend="or_op">|, ||</link>
+            </member>
+            <member>
+                <link linkend="and_op">&amp;, &amp;&amp;</link>
+            </member>
+            <member>
+                <link linkend="or">or</link>
+            </member>
+            <member>
+                <link linkend="and">and</link>
+            </member>
+            <member>
+                <link linkend="bin2dec">bin2dec</link>
+            </member>
+            <member>
+                <link linkend="dec2bin">dec2bin</link>
+            </member>
+        </simplelist>
+    </refsection>
+    <refsection role="history">
+        <title>История</title>
+        <revhistory>
+            <revision>
+                <revnumber>5.0</revnumber>
+                <revdescription>
+                    Функция введена.
+                </revdescription>
+            </revision>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revdescription>
+                    <itemizedlist>
+                        <listitem>
+                            Теперь поддерживаются 64-битные целые числа.
+                        </listitem>
+                        <listitem>
+                            Добавлена поддержка для положительных знаковых целых чисел.
+                        </listitem>
+                        <listitem>
+                            Для десятичных чисел биты от №53 до №1024 теперь могут быть должным образом установлены.
+                        </listitem>
+                        <listitem>
+                            Для каждого входного элемента теперь несколько битов могут быть установлены одновременно.
+                        </listitem>
+                        <listitem>
+                          Входные аргументы теперь могут смешивать массивы и скаляры вместо обязательных
+                          поэлементных массивов.
+                        </listitem>
+                    </itemizedlist>
+                </revdescription>
+            </revision>
+        </revhistory>
     </refsection>
 </refentry>
index 8fa11a8..b47408c 100644 (file)
@@ -1,7 +1,5 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2008 - INRIA - Pierre MARECHAL
-//
-// Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2019 - Samuel GOUGEON
 //
 // 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.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-function y = bitset(x,pos,v)
-
-    // INRIA 2008 - Pierre MARECHAL
-    //
-    // BITSET function
-    // Set bit at specified position
-
-    // Check input arguments
-    // =========================================================================
-
-    // check number input argument
-
-    rhs = argn(2);
+function y = bitset(x, pos, v)
+    fname = "bitset"
+    rhs = argn(2)
 
-    if rhs < 2 then
-        msg = _("%s: Wrong number of input argument(s): At least %d expected.\n")
-        error(msprintf(msg, "bitset", 2));
+    // CHECKING AND FORMATTING INPUT ARGUMENTS
+    // =======================================
+    if rhs < 2 | rhs > 3 then
+        msg = _("%s: Wrong number of input arguments: %d or %d expected.\n")
+        error(msprintf(msg, fname, 2, 3))
     end
 
-    // case empty matrix
-    if isempty(x)
-        if ~isempty(pos) & prod(size(pos))<>1
-            msg = _("%s: Wrong size for input arguments: Same sizes expected.\n")
-            error(msprintf(msg, "bitset"));
-        else
-            y=[]
-            return
-        end
+    // Check x
+    // -------
+    if x==[]
+        y = []
+        return
     end
-
-    // check v value
-    if rhs == 3 & or(v <> 0 & v <> 1) then
-        msg = _("%s: Wrong value for input argument #%d: 0 or 1 expected.\n")
-        error(msprintf(msg, "bitset",3));
-    elseif rhs == 2 then
-        v = ones(x);
-    end
-
-    // check size
-    if or(size(x) <> size(pos)) | or(size(v) <> size(x)) then
-        msg = _("%s: Wrong size for input arguments: Same sizes expected.\n")
-        error(msprintf(msg, "bitset"));
+    if  and(type(x)<>[1 8]) | (type(x)==1 & (~isreal(x)|or((x-floor(x))<>0))) | or(x<0)
+        msg = gettext("%s: Argument #%d: Non-negative real integers expected.\n")
+        error(msprintf(msg, fname, 1))
     end
 
-    // check type
-    if (type(x) == 1  & (or(x-floor(x) <> 0) | or(x < 0))) ..
-        | (type(x) == 8  & (inttype(x) < 10)) ..
-        | (typeof(x) == "hypermat" & (or(x-floor(x) <> 0) | or(x < 0))) ..
-        | (type(x) <> 1 & type(x) <> 8 & typeof(x) <> "hypermat") then
-        msg = _("%s: Wrong type for input argument #%d: Scalar/matrix/hypermatrix of unsigned integers expected.\n")
-        error(msprintf(msg, "bitset",1));
+    // Check pos
+    // ---------
+    if ~isdef("pos","l") | pos==[] then     // do nothing, keep it as is
+        y = x
+        return
     end
-
-    if (type(pos) == 1  & (or(pos-floor(pos) <> 0) | or(pos < 0))) ..
-        | (type(pos) == 8  & (inttype(pos) < 10)) ..
-        | (typeof(pos) == "hypermat" & (or(pos-floor(pos) <> 0) | or(pos < 0))) ..
-        | (type(pos) <> 1 & type(pos) <> 8 & typeof(pos) <> "hypermat") then
-        msg = _("%s: Wrong type for input argument #%d: Scalar/matrix/hypermatrix of unsigned integers expected.\n")
-        error(msprintf(msg, "bitset",2));
-    end
-
-    // check pos value
-    select inttype(x(1))
-    case 0  then posmax = 52;
-    case 11 then posmax = 8;
-    case 12 then posmax = 16;
-    case 14 then posmax = 32;
-    end
-
-    if or(pos > posmax) | or(pos < 1) then
-        msg = _("%s: Wrong value for input argument #%d: Must be between %d and %d.\n")
-        error(msprintf(msg, "bitset", 2, 1, posmax));
-    end
-
-    // Algorithm
-    // =========================================================================
-
-    if size(pos,"*") == 1;
-        pos  = ones(x)*pos;
+    if  (type(pos)<>1  & type(pos)<>8) |  ..
+        (type(pos)==1  & (or((pos-floor(pos))<>0) | ~isreal(pos))) | or(pos<1)
+        msg = gettext("%s: Argument #%d: integers > 0 expected.\n")
+        error(msprintf(msg, fname, 2))
+    else
+        // max value
+        icode = inttype(x)
+        select modulo(icode,10)
+        case 0  then posmax = 1024  // log2(number_properties("huge"))
+        case 1 then posmax = 8
+        case 2 then posmax = 16
+        case 4 then posmax = 32
+        case 8 then posmax = 64
+        end
+        if icode>0 & icode<10      // Signed integers
+            posmax = posmax-1      // => sign bit reserved
+        end
+        if or(pos > posmax)
+            msg = gettext("%s: Argument #%d: Integers <= %d expected.\n")
+            error(msprintf(msg, fname, 2, posmax))
+        end
     end
-
-    if size(x,"*") == 1;
-        x    = ones(pos)*x;
+    // Check consistency between x and pos sizes
+    sx = size(x)
+    ndx = ndims(x)
+    sp = size(pos)
+    ndp = ndims(pos)
+    sameBits = ndp<ndx | ~and(sx(1:ndx)==sp(1:ndx)) // Same bits for all x components
+    if sameBits then
+        if ~isscalar(pos) & ~isvector(pos)
+            msg = gettext("%s: Arguments #%d and #%d: Incompatible sizes.\n")
+            error(msprintf(msg, fname, 1, 2))
+        end
+        if ~isdef("v","l") | size(v,"*")==1
+            pos = unique(pos)
+            // we can't do that if an array v is provided, because then
+            // its length must match the pos one.
+        else
+            if length(pos)>posmax
+                msg = gettext("%s: Argument #%d is longer than %d. Please check against duplicate values.\n")
+                error(msprintf(msg, fname, 2, posmax))
+            end
+        end
+    else // ndp>=ndx & and(sx(1:ndx)==sp(1:ndx))
+        pos = matrix(pos,[sx -1])
+        // duplicate values along a range can't be removed nor easily canceled.
+        // So, no check. Never mind.
     end
 
-    vZero = find(v == 0);
-    vOne = find(v == 1);
-    sz = size(x);
-
-    if type(x(1)) == 8 then
-
-        select inttype(x(1))
-        case 11 then mask = 2^uint8((pos(:)-1));
-        case 12 then mask = 2^uint16((pos(:)-1));
-        case 14 then mask = 2^uint32((pos(:)-1));
+    // Check v
+    // -------
+    // At the end, v must be either a vector with the pos's length (sameBits case)
+    // or an array with same sizes as pos (element-wise case)
+    if ~isdef("v","l") || v==[] then
+        v = ones(pos)
+    else
+        if  (type(v)<>1  & type(v)<>8) || or(v~=0 & v~=1)
+            msg = _("%s: Argument #%d: Must be in the set {%s}.\n")
+            error(msprintf(msg, fname, 3, "0,1"))
         end
-        mask = matrix(mask, sz);
-        y(vZero) = x(vZero) & (~mask(vZero));
-        y(vOne) = x(vOne) | mask(vOne);
-        y = matrix(y, sz);
-
-        return;
+        if prod(size(v)(1:min(ndims(v),ndims(pos)))) == 1 // scalar or hypercolumn cases
+            v = v .*. ones(pos)
+        elseif prod(size(v)(1:ndims(pos))) ~= length(pos)
+            msg = gettext("%s: Arguments #%d and #%d: Incompatible sizes.\n")
+            error(msprintf(msg, fname, 2, 3))
+        end
+    end
 
+    // PROCESSING
+    // ==========
+    if sameBits then
+        nBitLayers = length(pos)
+        template = ones(x)
     else
-        // type == 1
-        a     = 2^32;
-        mask  = uint32(zeros(pos));
-
-        y_MSB  = uint32(zeros(pos));
-        y_LSB  = uint32(zeros(pos));
-
-        y_LSB = uint32( x - double(uint32(x/a)) * a ); // LSB Less Significant Bits
-        y_MSB = uint32( x/a );                         // MSB Most Significant Bits
-        yMSB  = y_MSB;
-        yLSB  = y_LSB;
-
-        if or(pos<=32) then
-            mask(pos<=32) = uint32(2^(pos(pos<=32) -1));
-            yLSB = y_LSB(pos<=32);
-            ymask = mask(pos<=32);
-            // v == 0
-            yLSB(vZero) = yLSB(vZero) & (~ymask(vZero));
-            // v == 1
-            yLSB(vOne) = yLSB(vOne) | ymask(vOne);
-            yLSB = matrix(yLSB, sz);
+        nBitLayers = size(pos,ndx+1)
+        // Extraction mask:
+        str = strcat(emptystr(1,ndx)+":,")+"iL"
+    end
+    Pos = pos
+    V = v
+    y = x
+    //
+    for iL = 1:nBitLayers
+        if sameBits
+            pos = template*Pos(iL)
+            v   = template*V(iL)
+        else
+            execstr("pos = Pos("+str+"); v = V("+str+")")
         end
-
-        if or(pos>32) then
-            mask(pos>32) = uint32(2^(pos(pos>32) -32 -1));
-            yMSB = y_MSB(pos>32);
-            ymask = mask(pos>32);
-            yMSB(vZero) = yMSB(vZero) & (~ymask(vZero));
-            yMSB(vOne) = yMSB(vOne) | ymask(vOne);
-            // v == 0
-            yMSB(vZero) = yMSB(vZero) & (~ymask(vZero));
-            // v == 1
-            yMSB(vOne) = yMSB(vOne) | ymask(vOne);
-            yMSB = matrix(yMSB, sz);
+        vZero = (v == 0)
+        vOne  = (v == 1)
+        x = y
+        if type(x)==8 then
+            mask =  2 .^ iconvert((pos-1), inttype(x))
+            y(vZero) = x(vZero) & (~mask(vZero))
+            y(vOne) = x(vOne) | mask(vOne)
+            y = matrix(y,sx)
+        else
+            b = bitget(x, pos)
+            tmp = vOne & b==0
+            if or(tmp)
+                y(tmp) = y(tmp) + 2 .^(pos(tmp)-1)
+            end
+            tmp = vZero & b==1
+            if or(tmp)
+                y(tmp) = y(tmp) - 2 .^(pos(tmp)-1)
+            end
         end
-        y = double(a * yMSB + yLSB);
     end
-
 endfunction
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/bitset.dia.ref b/scilab/modules/elementary_functions/tests/unit_tests/bitset.dia.ref
deleted file mode 100644 (file)
index eee2b67..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// <-- CLI SHELL MODE -->
-assert_checkequal(bitset(uint8(9), 5), uint8(25));
-assert_checkequal(bitset(uint8(25), 5, 0), uint8(9));
-assert_checkequal(bitset(25, 5, 0), 9);
-assert_checkerror("bitset(2)",[],10000);
-assert_checkerror("bitset(""aze"")",[],10000);
-assert_checkerror("bitset(-25, 5)",[],10000);
-a=[170,82,24,89,92,59,220,141];
-assert_checkequal(bitset(a, ones(1:8)), [171,83,25,89,93,59,221,141]);
index 89fbfa8..85a8f70 100644 (file)
-// =============================================================================
+// ===================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2019 - Samuel GOUGEON
 //
 //  This file is distributed under the same license as the Scilab package.
-// =============================================================================
+// ===================================================================
 
+// <-- ENGLISH IMPOSED -->
 // <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
 
 assert_checkequal(bitset(uint8(9), 5), uint8(25));
 assert_checkequal(bitset(uint8(25), 5, 0), uint8(9));
 assert_checkequal(bitset(25, 5, 0), 9);
 
-assert_checkerror("bitset(2)",[],10000);
-assert_checkerror("bitset(""aze"")",[],10000);
-
-assert_checkerror("bitset(-25, 5)",[],10000);
-a=[170,82,24,89,92,59,220,141];
+a = [170,82,24,89,92,59,220,141];
 assert_checkequal(bitset(a, ones(1:8)), [171,83,25,89,93,59,221,141]);
+
+// x matrix ; pos scalar
+assert_checkequal(bitset([0 1;2 3], 3), [4 5;6 7]);
+// x matrix ; pos = same sizes
+assert_checkequal(bitset([0 1;2 3], [3 4;5 6]), [4 9; 18 35]);
+
+// =====================
+// Element-wise settings
+// =====================
+dataTypes = list(double, int8, uint8, int16, uint16, int32, uint32, int64, uint64);
+shifts = [1000, 1, 1, 9, 9, 25, 25, 57, 57];
+
+// With default bits values v = ones()
+// ===================================
+// Only one bit
+// ------------
+pos = cat(3, [0 1 2 ; 3 2 1], [1 3 1 ; 2 1 3]);
+X = zeros(2, 3, 2);
+for i = 1:9         // Loop over inttypes
+    iconv = dataTypes(i);
+    x = iconv(X);
+    s = shifts(i); sm1 = s - 1;
+    // on a row
+    y = bitset(x(:)', s+pos(:)');
+    assert_checkequal(y/(2^sm1), iconv(2.^pos(:)'));
+    // on a column
+    y = bitset(x(:), s+pos(:));
+    assert_checkequal(y/(2^sm1), iconv(2.^pos(:)));
+    // on a matrix
+    y = bitset(x(:,:,1), s+pos(:,:,1));
+    assert_checkequal(y/(2^sm1), iconv(2.^pos(:,:,1)));
+    // on a hypermatrix
+    y = bitset(x, s+pos);
+    assert_checkequal(y/(2^sm1), iconv(2.^pos));
+end
+
+// Several bits
+// ------------
+pos = matrix(permute(grand(12,"prm",0:6)(:,1:3),[1 4 3 2]), 2,3,2,-1);
+// 12 series of 3 random bits pos among 0:6 with no duplicate in triplets
+X = zeros(2,3,2);
+for i = 1:9         // Loop over inttypes
+    iconv = dataTypes(i);
+    x = iconv(X);
+    s = shifts(i); sm1 = s - 1;
+    // on a scalar
+    p = [3 2 5 1];
+    y = bitset(x(1), s+p);
+    assert_checkequal(y/(2^sm1), iconv(sum(2.^p)));
+    // on a row
+    p = matrix(pos,1,12,-1);
+    y = bitset(x(:)', s+p);
+    assert_checkequal(y/(2^sm1), iconv(sum(2.^p, 3)));
+    // on a column
+    p = matrix(pos,12,1,-1);
+    y = bitset(x(:), s+p);
+    assert_checkequal(y/(2^sm1), iconv(sum(2.^p, 3)));
+    // on a matrix
+    p = matrix(pos(:,:,1,:),2,3,-1);
+    y = bitset(x(:,:,1), s+p);
+    assert_checkequal(y/(2^sm1), iconv(sum(2.^p, 3)));
+    // on a hypermatrix
+    y = bitset(x, s+pos);
+    assert_checkequal(y/(2^sm1), iconv(sum(2.^pos, 4)));
+end
+
+// ===========================
+// With explicit bits values v
+// ===========================
+X = matrix([grand(1,3,"uin",0,9) grand(1,9,"uin",10,100)],2,3,2);
+
+// Only one bit assigned per input target
+// --------------------------------------
+pos = cat(3, [0 1 2 ; 3 2 1], [1 3 1 ; 2 1 3])+1;
+B = matrix(bitget(X(:)', pos(:)'), 2,3,2);      // current bits values
+for v = list(0, 1, grand(2,3,2,"uin",0,1))  // new bits values to assign
+    // Preparing the expected answer
+    rep = X;    // Initialization, OK where B==V
+    if v==0
+        w = B==1; if or(w), rep(w) = X(w) - 2.^(pos(w)-1); end
+    elseif v==1
+        w = B==0; if or(w), rep(w) = X(w) + 2.^(pos(w)-1); end
+    else
+        w = B>v; if or(w), rep(w) = X(w) - 2.^(pos(w)-1); end
+        w = B<v; if or(w), rep(w) = X(w) + 2.^(pos(w)-1); end
+    end
+    // Tests
+    for i = 1:9         // Loop over inttypes
+        iconv = dataTypes(i);
+        x = iconv(X);
+        // on a row
+        y = bitset(x(:)', pos(:)', v(:)');
+        assert_checkequal(y, iconv(rep(:)'));
+        // on a column
+        y = bitset(x(:), pos(:), v(:));
+        assert_checkequal(y, iconv(rep(:)));
+        // on a matrix
+        y = bitset(x(:,:,1), pos(:,:,1), v(:,:,1));
+        assert_checkequal(y, iconv(rep(:,:,1)));
+        // on a hypermatrix
+        y = bitset(x, pos, v);
+        assert_checkequal(y, iconv(rep));
+    end
+end
+// Several bits assigned per input
+// -------------------------------
+n = 3;
+pos = matrix(permute(grand(12,"prm",0:3)(:,1:n),[1 4 3 2]), 2,3,2,-1)+1;
+// 12 series of n random bits pos among 0:3 with no duplicate in triplets
+V = grand(2,3,2,n,"uin",0,1);   // New bits values to assign
+B = zeros(pos);                 // current bits values:
+// Computing the expected answer
+rep = X;
+for dim = 1:n
+    p = pos(:,:,:,dim);
+    b = bitget(X, p);
+    v = V(:,:,:,dim);
+    w = b>v; if or(w), rep(w) = rep(w) - 2.^(p(w)-1); end
+    w = b<v; if or(w), rep(w) = rep(w) + 2.^(p(w)-1); end
+end
+// Tests
+for i = 1:9         // Loop over inttypes
+    iconv = dataTypes(i);
+    x = iconv(X);
+    // on a row
+    y = bitset(x(:)', matrix(pos,1,-1,n), matrix(V,1,-1,n));
+    assert_checkequal(y, iconv(rep(:)'));
+    // on a column
+    y = bitset(x(:), matrix(pos,-1,1,n), matrix(V,-1,1,n));
+    assert_checkequal(y, iconv(rep(:)));
+    // on a matrix
+    y = bitset(x(:,:,1), matrix(pos(:,:,1,:),2,3,-1), matrix(V(:,:,1,:),2,3,-1));
+    assert_checkequal(y, iconv(rep(:,:,1)));
+    // on a hypermatrix
+    y = bitset(x, pos, V);
+    assert_checkequal(y, iconv(rep));
+end
+
+
+// ===============
+// Errors handling
+// ===============
+msg = "bitset: Wrong number of input arguments: 2 or 3 expected.";
+assert_checkerror("bitset()", msg);
+assert_checkerror("bitset(1)", msg);
+assert_checkerror("bitset(1,1,1,1)", "Wrong number of input arguments.");
+
+msg = "bitset: Argument #1: Non-negative real integers expected.";
+assert_checkerror("bitset(%z, 1)", msg);
+assert_checkerror("bitset(%t, 1)", msg);
+assert_checkerror("bitset(-1, 1)", msg);
+assert_checkerror("bitset(int8(-30), 1)", msg);
+assert_checkerror("bitset(1+0*%i, 1)", msg);
+assert_checkerror("bitset(1.5, 1)", msg);
+
+msg = "bitset: Argument #2: integers > 0 expected.";
+assert_checkerror("bitset([10 20], %t)", msg);
+assert_checkerror("bitset([10 20], 1+0*%z)", msg);
+assert_checkerror("bitset([10 20], 1+0*%i)", msg);
+assert_checkerror("bitset([10 20], 0)", msg);
+assert_checkerror("bitset([10 20], 0.5)", msg);
+assert_checkerror("bitset([10 20], 1.5)", msg);
+
+msg = "bitset: Argument #2: Integers <= %d expected.\n";
+assert_checkerror("bitset([10 20], 1200)", msprintf(msg, 1024));
+assert_checkerror("bitset(  int8([10 20]),  8)", msprintf(msg, 7));
+assert_checkerror("bitset( uint8([10 20]),  9)", msprintf(msg, 8));
+assert_checkerror("bitset(uint16([10 20]), 17)", msprintf(msg, 16));
+assert_checkerror("bitset( int16([10 20]), 16)", msprintf(msg, 15));
+assert_checkerror("bitset( int32([10 20]), 32)", msprintf(msg, 31));
+assert_checkerror("bitset(uint32([10 20]), 33)", msprintf(msg, 32));
+assert_checkerror("bitset(uint64([10 20]), 65)", msprintf(msg, 64));
+assert_checkerror("bitset( int64([10 20]), 64)", msprintf(msg, 63));
+
+msg = "bitset: Arguments #1 and #2: Incompatible sizes.";
+assert_checkerror("bitset([10 20], [1 3 ; 2 4])", msg);
+assert_checkerror("bitset([1 2 3 4], [1 3 ; 1 2])", msg);
+
+msg = "bitset: Argument #2 is longer than 7. Please check against duplicate values.";
+assert_checkerror("bitset(int8([10 20]), [1 2 2 3 4 4 5 6 6], [1 0 0 0 1 1 0 1 0])", msg);
+
+msg = "bitset: Argument #3: Must be in the set {0,1}.";
+assert_checkerror("bitset([10 20], 3, 2)", msg);
+assert_checkerror("bitset([10 20], 3, 0.5)", msg);
+assert_checkerror("bitset([10 20], 3, -3)", msg);
+
+msg = "bitset: Arguments #2 and #3: Incompatible sizes.";
+assert_checkerror("bitset([10 20], 3, [1 0])", msg);
+assert_checkerror("bitset([10 20], [3 6], [0 1 1])", msg);
index 1cf8e08..2934032 100644 (file)
                     <li>Several bits can now be retrieved from each component of an input array.</li>
                 </ul>
             </li>
+            <li><code>bitset</code> is upgraded:
+                <ul>
+                    <li>It now accepts positive Signed encoded integers.</li>
+                    <li>It now supports the new uint64 and int64 types of encoded integers.</li>
+                    <li>For decimal numbers: bits with indices > 32 can now be set (up to #1024).</li>
+                    <li>Several bits can now be set for each input component.</li>
+                    <li>Distributive scalar inputs are now accepted.</li>
+                </ul>
+            </li>
             <li><code>edit</code> now accepts a line number as text (like "23").</li>
             <li><code>profileEnable, profileDisable, profileGetInfo</code> could be used to instrument functions and gather execution information within Scilab.</li>
             <li><code>prettyprint</code> is upgraded: