* Bug 15830 fixed: linspace() was not reliable with encoded integers 79/20579/8
Samuel GOUGEON [Mon, 22 Oct 2018 23:45:45 +0000 (01:45 +0200)]
  http://bugzilla.scilab.org/15830

Change-Id: I55f61bcc62b5d1819a5c0c28099847395ffe0637

scilab/CHANGES.md
scilab/modules/elementary_functions/help/en_US/elementarymatrices/linspace.xml
scilab/modules/elementary_functions/help/fr_FR/elementarymatrices/linspace.xml
scilab/modules/elementary_functions/help/ru_RU/elementarymatrices/linspace.xml
scilab/modules/elementary_functions/macros/linspace.sci
scilab/modules/elementary_functions/tests/unit_tests/linspace.dia.ref [deleted file]
scilab/modules/elementary_functions/tests/unit_tests/linspace.tst
scilab/modules/elementary_functions/tests/unit_tests/linspace_uint64.tst [new file with mode: 0644]

index bc37421..42b6503 100644 (file)
@@ -676,6 +676,7 @@ Known issues
 * [#15817](http://bugzilla.scilab.org/show_bug.cgi?id=15817): `ascii(c)` with c>=128 crashed on OSX.
 * [#15818](http://bugzilla.scilab.org/show_bug.cgi?id=15818): `polarplot()` example could not be subplotted. `polarplot`'s demo did not display 'View code' and too often prompted the user.
 * [#15827](http://bugzilla.scilab.org/show_bug.cgi?id=15828): After `bode(..'rad')`, abscissae were titled 'Fréquence' instead of 'Pulsation' in french, and datatips still shew 'Hz' instead of 'rad/s'.
+* [#15830](http://bugzilla.scilab.org/show_bug.cgi?id=15830): `linspace` was not reliable for series of encoded integers.
 * [#15847](http://bugzilla.scilab.org/show_bug.cgi?id=15847): Scilab crashed at startup.
 * [#15850](http://bugzilla.scilab.org/show_bug.cgi?id=15850): Adding a space after a string increases its size.
 * [#15853](http://bugzilla.scilab.org/show_bug.cgi?id=15853): `mlist("cblock")` displayed endlessly "operation +: Warning adding..."
index 8fa81d3..f493808 100644 (file)
@@ -2,9 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2008 - INRIA
- * Copyright (C) 2016 - Samuel GOUGEON
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2016, 2018 - 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.
@@ -38,7 +37,7 @@
                 <term>x1, x2</term>
                 <listitem>
                     <para>
-                        Real or complex scalars:
+                        Real or complex scalars, or encoded integer scalars:
                         Bounds between which values must be generated.
                     </para>
                 </listitem>
@@ -47,7 +46,8 @@
                 <term>Col1, Col2</term>
                 <listitem>
                     <para>
-                        Column vectors of same heights of real or complex numbers.
+                        Column vectors of real or complex numbers, or of encoded integers,
+                        of same heights.
                     </para>
                 </listitem>
             </varlistentry>
             and <literal>n</literal> columns. We get
             <literal>Matrix(i,:) = linspace(Col1(i), Col2(i), n)</literal>.
         </para>
+        <warning>
+            When specified bounds are encoded integers, the actual step may vary by one unit
+            along the generated series.
+        </warning>
     </refsection>
     <refsection>
         <title>Examples</title>
 linspace(1, %pi, 0)         // n = 0
 linspace(1, 2, 10)          // x2 > x1 : increasing values
 linspace(2, 1, 10)          // x2 < x1 : decreasing values
-linspace(1+%i, 2-2*%i, 5)      // with complex numbers
-linspace([1:4]', [5:8]', 10)   // with input columns
+linspace(1+%i, 2-2*%i, 5)     // with complex numbers
+linspace([1:4]', [5:8]', 10)  // with input columns
  ]]></programlisting>
-        <screen><![CDATA[--> linspace(1, %pi, 0)    // n = 0
+        <screen><![CDATA[
+--> linspace(1, %pi, 0)    // n = 0
  ans  =
     []
 
@@ -132,17 +137,14 @@ linspace([1:4]', [5:8]', 10)   // with input columns
  ans  =
    1.   1.111   1.222   1.333   1.444   1.556   1.667   1.778   1.889   2.
 
-
 --> linspace(2, 1, 10)    // x2 &lt; x1 : decreasing values
  ans  =
    2.   1.889   1.778   1.667   1.556   1.444   1.333   1.222   1.111   1.
 
-
 --> linspace(1+%i, 2-2*%i, 5)      // with complex numbers
  ans  =
    1. +i     1.25 +0.25i   1.5 -0.5i   1.75 -1.25i   2. -2.i
 
-
 --> linspace([1:4]', [5:8]', 10)   // with input columns
  ans  =
    1.   1.444   1.889   2.333   2.778   3.222   3.667   4.111   4.556   5.
@@ -150,6 +152,26 @@ linspace([1:4]', [5:8]', 10)   // with input columns
    3.   3.444   3.889   4.333   4.778   5.222   5.667   6.111   6.556   7.
    4.   4.444   4.889   5.333   5.778   6.222   6.667   7.111   7.556   8.
 ]]></screen>
+    <para/>
+    <para>
+        <emphasis role="bold">With encoded integers:</emphasis>
+        The step may vary by one unit along the series:
+    </para>
+        <programlisting role="example"><![CDATA[
+x = linspace(int8([5;127]), int8([127;5]), 10)
+x(:,1:$-1) - x(:,2:$)
+ ]]></programlisting>
+        <screen><![CDATA[
+--> x = linspace(int8([5;127]), int8([127;5]), 10)
+ ans  =
+    5   18   32  45  59  72  86  99  113  127
+  127  114  100  87  73  60  46  33   19    5
+
+--> x(:,1:$-1) - x(:,2:$)
+ ans  =
+ -13 -14 -13 -14 -13 -14 -13 -14 -14
+  13  14  13  14  13  14  13  14  14
+]]></screen>
     </refsection>
     <refsection role="see also">
         <title>See also</title>
@@ -190,6 +212,12 @@ linspace([1:4]', [5:8]', 10)   // with input columns
                     </itemizedlist>
                 </revremark>
             </revision>
+            <revision>
+                <revnumber>6.0.2</revnumber>
+                <revremark>
+                    linspace() can now be reliably used for series of encoded integers.
+                </revremark>
+            </revision>
         </revhistory>
     </refsection>
 </refentry>
index 12d9b3c..c3e6e96 100644 (file)
@@ -2,9 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2008 - INRIA
- * Copyright (C) 2016 - Samuel GOUGEON
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2016, 2018 - 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.
@@ -38,7 +37,7 @@
                 <term>x1, x2</term>
                 <listitem>
                     <para>
-                        Nombres réels ou complexes scalaires : bornes entre
+                        Nombres réels ou complexes ou entiers encodés scalaires : bornes entre
                         lesquelles les valeurs doivent être générées.
                     </para>
                 </listitem>
@@ -47,8 +46,8 @@
                 <term>Col1, Col2</term>
                 <listitem>
                     <para>
-                        Vecteurs colonne de nombres réels ou complexes de même
-                        taille.
+                        Vecteurs colonne de nombres réels ou complexes ou entiers encodés, de mêmes
+                        tailles.
                     </para>
                 </listitem>
             </varlistentry>
@@ -56,8 +55,8 @@
                 <term>n</term>
                 <listitem>
                     <para>
-                        Nombre entier. Il précise le nombre de valeurs ou de colonnes à générer entre les deux extrémités (extrémités comprises).
-                        100 par défaut.
+                        Nombre entier positif. Il précise le nombre de valeurs ou de colonnes à
+                        générer entre les deux extrémités (extrémités comprises). 100 par défaut.
                     </para>
                 </listitem>
             </varlistentry>
             et <literal>n</literal> colonnes, avec
             <literal>Matrix(i,:) = linspace(Col1(i), Col2(i), n)</literal>.
         </para>
+        <warning>
+            Lorsque les bornes fournies sont des entiers encodés, le pas effectif observable
+            peut varier d'une unité le long de la série générée. Voir l'exemple ci-dessous.
+        </warning>
     </refsection>
     <refsection>
         <title>Exemples</title>
@@ -152,6 +155,26 @@ linspace([1:4]', [5:8]', 10)   // avec des colonnes de bornes
    3.   3.444   3.889   4.333   4.778   5.222   5.667   6.111   6.556   7.
    4.   4.444   4.889   5.333   5.778   6.222   6.667   7.111   7.556   8.
 ]]></screen>
+    <para/>
+    <para>
+        <emphasis role="bold">With encoded integers:</emphasis>
+        The step may vary by one unit along the series:
+    </para>
+        <programlisting role="example"><![CDATA[
+x = linspace(int8([5;127]), int8([127;5]), 10)
+x(:,1:$-1) - x(:,2:$)
+ ]]></programlisting>
+        <screen><![CDATA[
+--> x = linspace(int8([5;127]), int8([127;5]), 10)
+ ans  =
+    5   18   32  45  59  72  86  99  113  127
+  127  114  100  87  73  60  46  33   19    5
+
+--> x(:,1:$-1) - x(:,2:$)
+ ans  =
+ -13 -14 -13 -14 -13 -14 -13 -14 -14
+  13  14  13  14  13  14  13  14  14
+]]></screen>
     </refsection>
     <refsection role="see also">
         <title>Voir aussi</title>
@@ -193,6 +216,12 @@ linspace([1:4]', [5:8]', 10)   // avec des colonnes de bornes
                     </itemizedlist>
                 </revremark>
             </revision>
+            <revision>
+                <revnumber>6.0.2</revnumber>
+                <revremark>
+                    linspace() génère désormais de manière fiable les séries d'entiers encodés.
+                </revremark>
+            </revision>
         </revhistory>
     </refsection>
 </refentry>
index a13dcc4..2c57942 100644 (file)
@@ -2,9 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2008 - INRIA
- * Copyright (C) 2016 - Samuel GOUGEON
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2016, 2018 - 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.
@@ -38,7 +37,7 @@
                 <term>x1, x2</term>
                 <listitem>
                     <para>
-                        Вещественные или комплексные скаляры:
+                        Вещественные или комплексные скаляры, или кодированные целочисленные скаляры:
                         границы между которыми должны быть сгенерированы значения.
                     </para>
                 </listitem>
@@ -47,7 +46,8 @@
                 <term>Col1, Col2</term>
                 <listitem>
                     <para>
-                        Вектор-столбцы одинаковой высоты, состоящие из вещественных или комплексных чисел.
+                        Вектор-столбцы одинаковой высоты, состоящие из вещественных или комплексных
+                        чисел или кодированных целочисленных скаляров.
                     </para>
                 </listitem>
             </varlistentry>
             матрица <varname>Matrix</varname> имеет то же количество строк и
             <varname>n</varname> столбцов, которое мы получим <code>Matrix(i,:) = linspace(Col1(i), Col2(i), n)</code>.
         </para>
+        <warning>
+            В случае, когда указанные границы являются кодированными целыми числами, то фактический шаг
+            может колебаться на единицу в последовательности.
+        </warning>
     </refsection>
     <refsection>
         <title>Примеры</title>
@@ -147,6 +151,26 @@ linspace([1:4]', [5:8]', 10)   // со столбцами на входе
    3.   3.444   3.889   4.333   4.778   5.222   5.667   6.111   6.556   7.
    4.   4.444   4.889   5.333   5.778   6.222   6.667   7.111   7.556   8.
 ]]></screen>
+    <para/>
+    <para>
+        <emphasis role="bold">С кодированными целыми числами:</emphasis>
+        Шаг может колебаться на единицу в последовательности:
+    </para>
+        <programlisting role="example"><![CDATA[
+x = linspace(int8([5;127]), int8([127;5]), 10)
+x(:,1:$-1) - x(:,2:$)
+ ]]></programlisting>
+        <screen><![CDATA[
+--> x = linspace(int8([5;127]), int8([127;5]), 10)
+ ans  =
+    5   18   32  45  59  72  86  99  113  127
+  127  114  100  87  73  60  46  33   19    5
+
+--> x(:,1:$-1) - x(:,2:$)
+ ans  =
+ -13 -14 -13 -14 -13 -14 -13 -14 -14
+  13  14  13  14  13  14  13  14  14
+]]></screen>
     </refsection>
     <refsection role="see also">
         <title>Смотрите также</title>
@@ -187,6 +211,12 @@ linspace([1:4]', [5:8]', 10)   // со столбцами на входе
                     </itemizedlist>
                 </revremark>
             </revision>
+            <revision>
+                <revnumber>6.0.2</revnumber>
+                <revremark>
+                    Теперь linspace() может быть надёжно использован для последовательностей кодированных целых чисел.
+                </revremark>
+            </revision>
         </revhistory>
     </refsection>
 </refentry>
index d0d4915..654b850 100644 (file)
@@ -2,9 +2,8 @@
 // Copyright (C) INRIA
 // Copyright (C) DIGITEO - 2011 - Allan CORNET
 // Copyright (C) CNES - 2011 - Guillaume AZEMA
-// Copyright (C) 2016 - Samuel GOUGEON
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2016, 2018 - 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.
@@ -41,11 +40,15 @@ function y = linspace(d1, d2, n)
     if ~or(type(d2)==[1 5 8]) then
         error(msprintf(msg, "linspace", 2));
     end
+    if type(d1)==8 & type(d2)==8 & inttype(d1)~=inttype(d2) then
+        msg = gettext("%s: Arguments #%d and #%d: Same integer types expected.\n")
+        error(msprintf(msg, "linspace", 2));
+    end
     msg = gettext("%s: Argument #%d: %%nan and %%inf values are forbidden.\n")
-    if or(isinf(d1)) | or(isnan(d1)) then
+    if type(d1)~=8 & (or(isinf(d1)) | or(isnan(d1))) then
         error(msprintf(msg, "linspace", 1));
     end
-    if or(isinf(d2)) | or(isnan(d2)) then
+    if type(d2)~=8 & (or(isinf(d2)) | or(isnan(d2))) then
         error(msprintf(msg, "linspace", 2));
     end
 
@@ -61,14 +64,63 @@ function y = linspace(d1, d2, n)
 
     // PROCESSING
     // ----------
-    if n>1
-        y = ((d2-d1) * (0:n-1)) / (n-1) + d1 * ones(1,n);
+    if n==1
+        y = d2
+    elseif n==2
+        y = [d1 d2]
+    elseif n>2
+        if or(inttype(d1)==[8 18])
+            y = linspace_integers_64(d1,d2,n)
+        else
+            if type(d1)==8
+                span = double(d2) - double(d1)
+            else
+                span = d2 - d1
+            end
+            y = (span * (0:n-1)) / (n-1) + d1 * ones(1,n);
+        end
         // Forces the last value to be exactly the given d2:
         // http://bugzilla.scilab.org/10966
         y(:,$) = d2;
-    elseif n==1
-        y = d2
     else
         y = []
     end
 endfunction
+// -----------------
+function y = linspace_integers_64(d1,d2,n)
+        s = d2>=d1
+        span = zeros(d1)
+        if typeof(d1)=="int64"  then
+            span = uint64(span)
+        end
+        span(s) = d2(s) - d1(s)
+        span(~s) = d1(~s) - d2(~s)
+        step = span/(n-1)
+        y = iconvert(zeros(size(d1,1),n), inttype(d1))
+        if or(s)  // d2 > d1
+            y(s,:) = d1(s)*ones(1,n) + step(s)*(0:n-1)
+        end
+        if or(~s)
+            y(~s,:) = d1(~s)*ones(1,n) - step(~s)*(0:n-1)
+        end
+        y(:,$) = d2
+        // Computing the balancing corrections
+            // We computes actual intervals
+        if typeof(d1)=="uint64" then
+            i = int64(zeros(size(d1,1),n-1))
+            i(s, :) = y(s, 2:$)    -  y(s, 1:$-1)
+            i(~s,:) = y(~s, 1:$-1) -  y(~s, 2:$)
+        else // int64
+            i = diff(y,1,2);
+        end
+            // diff wrt the 1st interval's width
+        e = i - i(:,1) * ones(1,n-1)
+
+            // Computing corrections
+        S = mean(double(e), 'c') * ones(1,n-1)
+        cumE = cumsum(e, 'c')
+        cumS = cumsum(S, 'c')
+        delta = cumS - cumE
+        // Applying the corrections
+        y(:,2:$) = y(:,2:$) + delta
+endfunction
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/linspace.dia.ref b/scilab/modules/elementary_functions/tests/unit_tests/linspace.dia.ref
deleted file mode 100644 (file)
index bcbd57c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2008 - INRIA - Michael Baudin
-// Copyright (C) 2012 - Scilab Enterprises - Sylvestre Ledru
-// Copyright (C) 2016 - Samuel GOUGEON
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-
-// <-- CLI SHELL MODE -->
-
-// Basic use
-assert_checkequal(linspace(1,2,-1),[]);
-assert_checkequal(linspace(1,2,0),[]);
-assert_checkequal(linspace(1,2,1),2);
-assert_checkequal(linspace(1,2,2),[1,2]);
-assert_checkequal(linspace(0,100,101),0:100);
-computed = linspace(0,1,11);
-expected = [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.];
-assert_checkalmostequal(computed,expected);
-
-// Basic use with 12 and 14 which also test scaling
-computed = linspace(12,14,11);
-expected = [12. 12.2 12.4 12.6 12.8 13. 13.2 13.4 13.6 13.8 14.];
-assert_checkalmostequal(computed,expected);
-
-// Column inputs
-assert_checkequal(size(linspace([0;2],[2;5],5)),[2,5]);
-assert_checkequal(size(linspace([0;2],[2;5],2)),[2,2]);
-assert_checkequal(linspace([0;2],[2;5],2),[0,2;2,5]);
-assert_checkalmostequal(linspace([-1;2],[2;6],6), [-1,-0.4,0.2,0.8,1.4,2; 2,2.8,3.6,4.4,5.2,6]);
-
-// With complex bounds
-assert_checkequal(linspace(0,3-3*%i,4), (0:3)*(1-%i));
-assert_checkequal(linspace(3-3*%i,0,7), (3:-0.5:0)*(1-%i));
-expected = complex([1;1]*(1:-0.25:0), [0:0.5:2 ; 2:0.5:4]);
-assert_checkequal(linspace(1+%i*[0;2],[2;4]*%i,5),expected);
-
-// Perform a check on the size of the input arguments
-assert_checktrue(execstr('linspace(2,[2,2])','errcatch')<>0);
index bcbd57c..b264608 100644 (file)
@@ -2,12 +2,16 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) 2008 - INRIA - Michael Baudin
 // Copyright (C) 2012 - Scilab Enterprises - Sylvestre Ledru
-// Copyright (C) 2016 - Samuel GOUGEON
+// Copyright (C) 2016, 2018 - Samuel GOUGEON
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
 
 // <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+// Perform a check on the size of the input arguments
+assert_checktrue(execstr('linspace(2,[2,2])','errcatch')<>0);
 
 // Basic use
 assert_checkequal(linspace(1,2,-1),[]);
@@ -36,5 +40,13 @@ assert_checkequal(linspace(3-3*%i,0,7), (3:-0.5:0)*(1-%i));
 expected = complex([1;1]*(1:-0.25:0), [0:0.5:2 ; 2:0.5:4]);
 assert_checkequal(linspace(1+%i*[0;2],[2;4]*%i,5),expected);
 
-// Perform a check on the size of the input arguments
-assert_checktrue(execstr('linspace(2,[2,2])','errcatch')<>0);
+// With encoded integers
+a = linspace(uint8(5), uint8(127), 10);
+e = uint8([5  18  32  45  59  72  86  99  113  127]);
+assert_checkequal(a, e);
+a = linspace(uint8(127), uint8(5), 10);
+e2 = uint8([127  114  100  87  73  60  46  33  19  5]);
+assert_checkequal(a, e2);
+a = linspace(uint8([5;127]), uint8([127;5]), 10);
+assert_checkequal(a, [e ; e2]);
+   // tests with int64 and uint64 in the dedicated linspace_uint64.tst
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/linspace_uint64.tst b/scilab/modules/elementary_functions/tests/unit_tests/linspace_uint64.tst
new file mode 100644 (file)
index 0000000..3685609
--- /dev/null
@@ -0,0 +1,110 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+// ------
+// uint64
+// ------
+// Intervals with relative widths < %eps
+// .....................................
+// increasing
+a = linspace(uint64(2)^63, uint64(2)^63+5, 6)';
+assert_checkequal(diff(a,1,1), uint64(ones(5,1)));
+a = linspace(uint64(2)^63, uint64(2)^63+5, 10)';
+assert_checkequal(diff(a,1,1)', uint64([0 1 0 1 0 1 0 1 1]));
+
+// decreasing
+a = linspace(uint64(2)^63, uint64(2)^63-5, 6)'
+d = a(1:$-1)-a(2:$)
+assert_checkequal(d, uint64(ones(5,1)));
+a = linspace(uint64(2)^63, uint64(2)^63-5,10)'
+assert_checkequal(diff(a($:-1:1),1,1)', uint64([1 1 0 1 0 1 0 1 0]));
+
+// Big intervals with widths > 1/%eps
+// ..................................
+// increasing - scalar
+n = 3;
+a = linspace(uint64(1), uint64(2)^63, n)'
+d = diff(a,1,1);
+assert_checkequal((d(1)-d)', uint64([0 1]));
+// increasing - column-wise
+a = linspace(uint64([1 10]'), (uint64(2)^63)+[1 10]', n)'
+d = diff(a,1,1);
+assert_checkequal((d(:,1)*ones(1,n-1)-d)', uint64([0 0;0 0]));
+n = 11;
+a = linspace(uint64([1 17]'), (uint64(2)^63)+[1 56]', n)'      // OK
+d = diff(a,1,1);
+//assert_checkequal(ones(n-1,1)*d(1,:)-d, uint64([0 0;0 0]));  // http://bugzilla.scilab.org/15836
+
+// decreasing
+n = 3;
+a = linspace(uint64(2)^63, uint64(1), n)'
+d = diff(a($:-1:1),1,1);
+assert_checkequal((d-d(1))', uint64([0 1]));
+n = 11;
+a = linspace(uint64(2)^63, uint64(1), n)';        // http://bugzilla.scilab.org/15836
+d = diff(a($:-1:1),1,1);
+//assert_checkequal((d-d(1))', uint64([0 1]));
+
+// -----
+// int64
+// -----
+// Intervals with relative widths < %eps
+// .....................................
+// increasing
+n = 3;
+a = linspace(-(int64(2)^63), int64(2)^63-1, n)
+d = diff(a,1,2);
+assert_checkequal(d-d(1), int64([0 -1]));
+n = 4;
+a = linspace(-(int64(2)^63), int64(2)^63-1, n);
+d = diff(a,1,2)
+assert_checkequal(d-d(1), int64([0 0 0]));
+n = 11;
+a = linspace(-(int64(2)^63), int64(2)^63-1, n);
+d = diff(a,1,2)
+assert_checkequal(d-d(1), int64([0 -1  0 -1  0 -1  0 -1  0 -1]));
+
+// decreasing
+a = linspace(int64(2)^62, int64(2)^62-5, 6)'
+d = a(1:$-1)-a(2:$)
+assert_checkequal(d, int64(ones(5,1)));
+a = linspace(int64(2)^62, int64(2)^62-5,10)'
+assert_checkequal(diff(a($:-1:1),1,1)', int64([1 1 0 1 0 1 0 1 0]));
+
+// Big intervals with widths > 1/%eps
+// ..................................
+// increasing - scalar
+n = 3;
+a = linspace(int64(1), int64(2)^62, n)'
+d = diff(a,1,1);
+assert_checkequal((d(1)-d)', int64([0 1]));
+
+// increasing - column-wise
+a = linspace(int64([1 10]'), (int64(2)^62)+[1 10]', n)'
+d = diff(a,1,1);
+assert_checkequal((d(:,1)*ones(1,n-1)-d)', int64([0 0;0 0]));
+n = 11;
+a = linspace(int64([1 17]'), (int64(2)^62)+[1 56]', n)'       // OK
+d = diff(a,1,1);
+//assert_checkequal(ones(n-1,1)*d(1,:)-d, int64([0 0;0 0]));  // http://bugzilla.scilab.org/15836
+
+// decreasing
+n = 3;
+a = linspace(int64(2)^62, int64(1), n)'
+d = diff(a($:-1:1),1,1);
+assert_checkequal((d-d(1))', int64([0 1]));
+n = 11;
+a = linspace(int64(2)^62-1, int64(1), n)'
+d = diff(a($:-1:1),1,1);
+assert_checkequal((d-d(1))', int64([0 0 0 1 0 0 1 0 0 1]));
+n = 137;
+a = linspace(int64(2)^62-1, int64(1), n)';
+d = diff(a($:-1:1),1,1);
+assert_checkequal(max(abs(d-d(1))), int64(1));