* Bug #9825 fixed - assert_computedigits returns too much digits 91/18691/5
Simon Marchetto [Wed, 25 Jan 2017 12:57:09 +0000 (13:57 +0100)]
Change-Id: I78a147938aed4adcd1c6b30d806162c40fbf0bd3

scilab/CHANGES.md
scilab/modules/development_tools/macros/assert/assert_computedigits.sci
scilab/modules/development_tools/tests/unit_tests/assert/computedigits.dia.ref
scilab/modules/development_tools/tests/unit_tests/assert/computedigits.tst

index 9ca4e49..e6d333d 100644 (file)
@@ -357,6 +357,7 @@ Bug Fixes
 * [#9161](http://bugzilla.scilab.org/show_bug.cgi?id=9161): Multiple insertions at a repeated index in a sparse matrice wrongly updated it.
 * [#9288](http://bugzilla.scilab.org/show_bug.cgi?id=9288): Dynamic palette with the most used blocks
 * [#9451](http://bugzilla.scilab.org/show_bug.cgi?id=9451): `test_run` output did not clearly distinguish heading lines of modules and tests lines 
+* [#9825](http://bugzilla.scilab.org/show_bug.cgi?id=9825): `assert_computedigits` returns too much digits
 * [#9865](http://bugzilla.scilab.org/show_bug.cgi?id=9865): When making a plot with `point`(no line), no symbol was shown in the legend.
 * [#9876](http://bugzilla.scilab.org/show_bug.cgi?id=9876): Creating a complex structure with multiple hierarchy level and size failed.
 * [#9912](http://bugzilla.scilab.org/show_bug.cgi?id=9912): In case of missing translated help page, the default en_US was sometimes ignored
index 100eff3..cc2f319 100644 (file)
@@ -46,17 +46,22 @@ function d = assert_computedigits ( varargin )
         d( k & expected == %inf & computed <> %inf ) = dmin;
         d( k & expected == -%inf & computed <> -%inf ) = dmin;
         // From now, neither of computed, nor expected is infinity
-        kdinf=find(d==%inf);
+        kdinf = find(d==%inf);
         if ( kdinf <> [] ) then
             relerr = ones(expected)*%nan;
             relerr(kdinf) = abs(computed(kdinf)-expected(kdinf)) ./ abs(expected(kdinf));
+            // specific case of neighbour floats (whose relative error less or equal than %eps in Scilab)
+            k = find( relerr <= %eps );
+            if ( k <> [] ) then
+                d(k) = -log(2^(-52))/log(basis);
+            end
             k = find( relerr >= 1 );
-            if ( k<> [] ) then
+            if ( k <> [] ) then
                 d(k) = dmin;
             end
             k = find( d==%inf & relerr < 1 );
-            if ( k<> [] ) then
-                sigdig(k) = -log ( 2*relerr(k) ) ./ log(basis);
+            if ( k <> [] ) then
+                sigdig(k) = -log (relerr(k)) ./ log(basis);
                 d(k) = max ( sigdig(k) , dmin );
             end
         end
index 472b9f8..d5afa6a 100644 (file)
 // along with this program.
 // <-- CLI SHELL MODE -->
 // <-- ENGLISH IMPOSED -->
-function flag = MY_assert_equal ( computed , expected )
-    if computed==expected then
-        flag = 1;
-    else
-        flag = 0;
-    end
-    if flag <> 1 then bugmes();quit;end
-endfunction
 format("v",10);
-//
 dmax = -log(2^(-53))/log(10);
-//
-computed = assert_computedigits ( 1 , 1 );
-MY_assert_equal ( computed , dmax );
-//
-computed = assert_computedigits ( 0 , 0 );
-MY_assert_equal ( computed , dmax );
-//
-computed = assert_computedigits ( 1 , 0 );
-MY_assert_equal ( computed , 0 );
-//
-computed = assert_computedigits ( 0 , 1 );
-MY_assert_equal ( computed , 0 );
-//
-computed = assert_computedigits ( 3.1415926 , %pi );
-MY_assert_equal ( computed , 7.467037797136421240 );
-//
-computed = assert_computedigits ( 3.1415926 , %pi , 2 );
-MY_assert_equal ( computed , 24.804962643893318841037 );
-//
-computed = assert_computedigits ( [0 0 1 1] , [0 1 0 1] );
-MY_assert_equal ( computed , [dmax 0 0 dmax] );
-//
-computed = assert_computedigits(ones(3,2),ones(3,2));
-MY_assert_equal ( computed , dmax * ones(3,2) );
-//
-computed = assert_computedigits([%nan %nan %nan %nan],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [dmax 0 0 0] );
-//
-computed = assert_computedigits([%inf %inf %inf %inf],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [0 dmax 0 0] );
-//
-computed = assert_computedigits([-%inf -%inf -%inf -%inf],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [0 0 dmax 0] );
-//
-computed = assert_computedigits([0 0 0 0],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [0 0 0 dmax] );
-//
-computed = assert_computedigits(1.224646799D-16,8.462643383D-18);
-MY_assert_equal ( computed , 0 );
-//
-computed = assert_computedigits ( 1.2345 + %i*6.7891 , 1.23456789 + %i*6.789123456 );
-MY_assert_equal ( computed , 3.9586791728311578886235 );
-//
-// The sign bit of the number of digits may be wrong because
-// ieee(2); z=max(-0,0); 1/z is -%inf
-back = ieee();
-ieee(2);
-computed = assert_computedigits ( 1.e-305 , 0 );
-MY_assert_equal ( 1/computed , %inf );
-//
-computed = assert_computedigits ( 0 , 1.e-305 );
-MY_assert_equal ( 1/computed , %inf );
-ieee(back);
-//
-// An empirically found test case
-a = [
+digits =  assert_computedigits(1, 1);
+assert_checkalmostequal(digits, dmax);
+digits =  assert_computedigits(0, 0);
+assert_checkalmostequal(digits, dmax);
+digits =  assert_computedigits(1, 0);
+assert_checkalmostequal(digits, 0);
+digits =  assert_computedigits(0, 1);
+assert_checkalmostequal(digits, 0);
+digits =  assert_computedigits(1.1, 1.0);
+assert_checkalmostequal(digits, 1);
+digits =  assert_computedigits(0.9, 1.0);
+assert_checkalmostequal(digits, 1);
+digits =  assert_computedigits(3.1415926, %pi);
+assert_checkalmostequal(digits, 7.7680677928004016);
+for p=1:8
+  e = 10^p;
+  c = e + 0.1;
+  digits =  assert_computedigits(c, e);
+  assert_checkalmostequal(digits, p+1);
+  if p>1
+    c = strtod("1." + strcat(repmat("0", 1, p-1)) + "1");
+  else
+    c = 1.1;
+  end
+  e = 1;
+  digits =  assert_computedigits(c, e);
+  assert_checkalmostequal(digits, p);
+  e = 10^-p;
+  c = e + 10^(-p-1);
+  digits =  assert_computedigits(c, e);
+  assert_checkalmostequal(digits, 1);
+  digits =  assert_computedigits(c, c);
+  assert_checkalmostequal(digits, dmax);
+end
+// check special values
+digits =  assert_computedigits([%nan %nan %nan %nan], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [dmax 0 0 0]);
+digits =  assert_computedigits([%inf %inf %inf %inf], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [0 dmax 0 0]);
+digits =  assert_computedigits([-%inf -%inf -%inf -%inf], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [0 0 dmax 0]);
+digits =  assert_computedigits([10. 10. 10. 10.], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [0 0 0 dmax]);
+digits =  assert_computedigits(1.224646799D-16, 8.462643383D-18);
+assert_checkalmostequal(digits, 0);
+// check vector
+digits =  assert_computedigits([0 0 1 1], [0 1 0 1]);
+assert_checkalmostequal(digits, [dmax 0 0 dmax]);
+digits =  assert_computedigits(ones(3,2), ones(3,2));
+assert_checkalmostequal(digits, dmax * ones(3,2));
+c = [
+10.001
+10.01
+nearfloat("succ", 10)
+10.0
+3.14159
+%nan
+%nan
+10^15
+-10^15
+%inf
+];
+e = [
+10.
+10.
+10.
+10.
+%pi
+10.0
+%nan
+%inf
+-%inf
+%inf
+];
+expected_digits = [
+4.
+3.
+-log(2^(-52))/log(10)
+dmax
+6.0733160846496004
+0
+dmax
+0
+0
+dmax
+];
+digits =  assert_computedigits(c, e);
+assert_checkalmostequal(digits, expected_digits);
+// check with vector random permutation
+perm = grand(1, "prm", size(e, 'r'));
+cP = c(perm);
+eP = e(perm);
+digitsP = assert_computedigits(cP, eP);
+expected_digitsP = expected_digits(perm);
+assert_checkalmostequal(digitsP, expected_digitsP);
+// base 2
+digits =  assert_computedigits(1.5, 1, 2);
+assert_checkalmostequal(digits, 1);
+digits =  assert_computedigits(3.1415926, %pi, 2);
+assert_checkalmostequal(digits, 25.804963);
+c = [
 3.982729777831130693D-59
 2.584939414228211484D-26
 4.391531370352049090D+43
 1.725436586898508346D+68
 ];
-b = [
+e = [
 3.982729777831130693D-59
 2.584939414228211484D-26
 4.391531370352048595D+43
 1.725436586898508107D+68
 ];
-c = assert_computedigits ( a , b , 2 );
-e = [
+digits = assert_computedigits(c, e, 2);
+expected_digits = [
 53.
 53.
-51.977632
-51.678072
-];
-assert_checkalmostequal ( c , e , 1.e-7 );
-//
-// Check that the vectorization was correct, i.e. no specific
-// case in the processing of the data is forgotten.
-//
-function pI = permInverse(p)
-    // Given the permutation p, compute the
-    // inverse permutation pI.
-    N = size(p,"*")
-    pI(p) = (1:N)'
-endfunction
-a = [
-1.234567891234567891
-1.2345678912345678
-1.23456789123456
-1.234567891234
-1.2345678912
-1.23456789
-1.234567
-1.2345
-1.23
-1.2
-1.
-0.
-%nan
-%nan
-%nan
-%inf
-%inf
-%inf
--%inf
--%inf
--%inf
-0.
-0.
--0.
--0.
+52.
+52.
 ];
-N = size(a,"*");
-for k = 1 : 10
-    mprintf("Test #%d\n",k);
-    p1 = grand(1,"prm",(1:N)');
-    p2 = grand(1,"prm",(1:N)');
-    computed = a(p1);
-    expected = a(p2);
-    d1 = assert_computedigits(computed,expected);
-    // Permute both computed and expected with the same permutation p3:
-    // d must not change.
-    p3 = grand(1,"prm",(1:N)');
-    computedP = computed(p3);
-    expectedP = expected(p3);
-    d2 = assert_computedigits(computedP,expectedP);
-    // Apply inverse permutation on d2.
-    pI = permInverse(p3);
-    d2 = d2(pI);
-    assert_checkequal(d1,d2);
-end
-Test #1
-Test #2
-Test #3
-Test #4
-Test #5
-Test #6
-Test #7
-Test #8
-Test #9
-Test #10
+assert_checkalmostequal(digits, expected_digits);
+// check complex values
+digits =  assert_computedigits(1.2345 + %i*6.7891, 1.23456789 + %i*6.789123456);
+assert_checkalmostequal(digits, 4.2597091684951387);
+// the sign bit of the number of digits may be wrong because
+// ieee(2); z=max(-0,0); 1/z is -%inf
+back = ieee();
+ieee(2);
+digits =  assert_computedigits(1.e-305, 0);
+assert_checkalmostequal(1/digits, %inf);
+digits =  assert_computedigits(0, 1.e-305);
+assert_checkalmostequal(1/digits, %inf);
+ieee(back);
index fa0fe22..475a4eb 100644 (file)
 // <-- CLI SHELL MODE -->
 // <-- ENGLISH IMPOSED -->
 
-function flag = MY_assert_equal ( computed , expected )
-    if computed==expected then
-        flag = 1;
-    else
-        flag = 0;
-    end
-    if flag <> 1 then pause,end
-endfunction
 
 format("v",10);
 
-//
 dmax = -log(2^(-53))/log(10);
-//
-computed = assert_computedigits ( 1 , 1 );
-MY_assert_equal ( computed , dmax );
-//
-computed = assert_computedigits ( 0 , 0 );
-MY_assert_equal ( computed , dmax );
-//
-computed = assert_computedigits ( 1 , 0 );
-MY_assert_equal ( computed , 0 );
-//
-computed = assert_computedigits ( 0 , 1 );
-MY_assert_equal ( computed , 0 );
-//
-computed = assert_computedigits ( 3.1415926 , %pi );
-MY_assert_equal ( computed , 7.467037797136421240 );
-//
-computed = assert_computedigits ( 3.1415926 , %pi , 2 );
-MY_assert_equal ( computed , 24.804962643893318841037 );
-//
-computed = assert_computedigits ( [0 0 1 1] , [0 1 0 1] );
-MY_assert_equal ( computed , [dmax 0 0 dmax] );
-//
-computed = assert_computedigits(ones(3,2),ones(3,2));
-MY_assert_equal ( computed , dmax * ones(3,2) );
-//
-computed = assert_computedigits([%nan %nan %nan %nan],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [dmax 0 0 0] );
-//
-computed = assert_computedigits([%inf %inf %inf %inf],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [0 dmax 0 0] );
-//
-computed = assert_computedigits([-%inf -%inf -%inf -%inf],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [0 0 dmax 0] );
-//
-computed = assert_computedigits([0 0 0 0],[%nan %inf -%inf 0]);
-MY_assert_equal ( computed , [0 0 0 dmax] );
-//
-computed = assert_computedigits(1.224646799D-16,8.462643383D-18);
-MY_assert_equal ( computed , 0 );
-//
-computed = assert_computedigits ( 1.2345 + %i*6.7891 , 1.23456789 + %i*6.789123456 );
-MY_assert_equal ( computed , 3.9586791728311578886235 );
-//
-// The sign bit of the number of digits may be wrong because
-// ieee(2); z=max(-0,0); 1/z is -%inf
-back = ieee();
-ieee(2);
-computed = assert_computedigits ( 1.e-305 , 0 );
-MY_assert_equal ( 1/computed , %inf );
-//
-computed = assert_computedigits ( 0 , 1.e-305 );
-MY_assert_equal ( 1/computed , %inf );
-ieee(back);
 
-//
-// An empirically found test case
-a = [
+digits =  assert_computedigits(1, 1);
+assert_checkalmostequal(digits, dmax);
+
+digits =  assert_computedigits(0, 0);
+assert_checkalmostequal(digits, dmax);
+
+digits =  assert_computedigits(1, 0);
+assert_checkalmostequal(digits, 0);
+
+digits =  assert_computedigits(0, 1);
+assert_checkalmostequal(digits, 0);
+
+digits =  assert_computedigits(1.1, 1.0);
+assert_checkalmostequal(digits, 1);
+
+digits =  assert_computedigits(0.9, 1.0);
+assert_checkalmostequal(digits, 1);
+
+digits =  assert_computedigits(3.1415926, %pi);
+assert_checkalmostequal(digits, 7.7680677928004016);
+
+for p=1:8
+  e = 10^p;
+  c = e + 0.1;
+  digits =  assert_computedigits(c, e);
+  assert_checkalmostequal(digits, p+1);
+
+  if p>1
+    c = strtod("1." + strcat(repmat("0", 1, p-1)) + "1");
+  else
+    c = 1.1;
+  end
+  e = 1;
+  digits =  assert_computedigits(c, e);
+  assert_checkalmostequal(digits, p);
+
+  e = 10^-p;
+  c = e + 10^(-p-1);
+  digits =  assert_computedigits(c, e);
+  assert_checkalmostequal(digits, 1);
+
+  digits =  assert_computedigits(c, c);
+  assert_checkalmostequal(digits, dmax);
+end
+
+// check special values
+digits =  assert_computedigits([%nan %nan %nan %nan], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [dmax 0 0 0]);
+
+digits =  assert_computedigits([%inf %inf %inf %inf], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [0 dmax 0 0]);
+
+digits =  assert_computedigits([-%inf -%inf -%inf -%inf], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [0 0 dmax 0]);
+
+digits =  assert_computedigits([10. 10. 10. 10.], [%nan %inf -%inf 10.]);
+assert_checkalmostequal(digits, [0 0 0 dmax]);
+
+digits =  assert_computedigits(1.224646799D-16, 8.462643383D-18);
+assert_checkalmostequal(digits, 0);
+
+// check vector
+digits =  assert_computedigits([0 0 1 1], [0 1 0 1]);
+assert_checkalmostequal(digits, [dmax 0 0 dmax]);
+
+digits =  assert_computedigits(ones(3,2), ones(3,2));
+assert_checkalmostequal(digits, dmax * ones(3,2));
+
+c = [
+10.001
+10.01
+nearfloat("succ", 10)
+10.0
+3.14159
+%nan
+%nan
+10^15
+-10^15
+%inf
+];
+
+e = [
+10.
+10.
+10.
+10.
+%pi
+10.0
+%nan
+%inf
+-%inf
+%inf
+];
+
+expected_digits = [
+4.
+3.
+-log(2^(-52))/log(10)
+dmax
+6.0733160846496004
+0
+dmax
+0
+0
+dmax
+];
+digits =  assert_computedigits(c, e);
+assert_checkalmostequal(digits, expected_digits);
+
+// check with vector random permutation
+perm = grand(1, "prm", size(e, 'r'));
+cP = c(perm);
+eP = e(perm);
+digitsP = assert_computedigits(cP, eP);
+expected_digitsP = expected_digits(perm);
+assert_checkalmostequal(digitsP, expected_digitsP);
+
+// base 2
+digits =  assert_computedigits(1.5, 1, 2);
+assert_checkalmostequal(digits, 1);
+
+digits =  assert_computedigits(3.1415926, %pi, 2);
+assert_checkalmostequal(digits, 25.804963);
+
+c = [
 3.982729777831130693D-59
 2.584939414228211484D-26
 4.391531370352049090D+43
 1.725436586898508346D+68
 ];
-b = [
+e = [
 3.982729777831130693D-59
 2.584939414228211484D-26
 4.391531370352048595D+43
 1.725436586898508107D+68
 ];
-c = assert_computedigits ( a , b , 2 );
-e = [
+digits = assert_computedigits(c, e, 2);
+expected_digits = [
 53.
 53.
-51.977632
-51.678072
-];
-assert_checkalmostequal ( c , e , 1.e-7 );
-//
-// Check that the vectorization was correct, i.e. no specific
-// case in the processing of the data is forgotten.
-//
-function pI = permInverse(p)
-    // Given the permutation p, compute the
-    // inverse permutation pI.
-    N = size(p,"*")
-    pI(p) = (1:N)'
-endfunction
-
-a = [
-1.234567891234567891
-1.2345678912345678
-1.23456789123456
-1.234567891234
-1.2345678912
-1.23456789
-1.234567
-1.2345
-1.23
-1.2
-1.
-0.
-%nan
-%nan
-%nan
-%inf
-%inf
-%inf
--%inf
--%inf
--%inf
-0.
-0.
--0.
--0.
+52.
+52.
 ];
+assert_checkalmostequal(digits, expected_digits);
+
+// check complex values
+digits =  assert_computedigits(1.2345 + %i*6.7891, 1.23456789 + %i*6.789123456);
+assert_checkalmostequal(digits, 4.2597091684951387);
+
+// the sign bit of the number of digits may be wrong because
+// ieee(2); z=max(-0,0); 1/z is -%inf
+back = ieee();
+ieee(2);
+digits =  assert_computedigits(1.e-305, 0);
+assert_checkalmostequal(1/digits, %inf);
+
+digits =  assert_computedigits(0, 1.e-305);
+assert_checkalmostequal(1/digits, %inf);
+ieee(back);
+
 
-N = size(a,"*");
-for k = 1 : 10
-    mprintf("Test #%d\n",k);
-    p1 = grand(1,"prm",(1:N)');
-    p2 = grand(1,"prm",(1:N)');
-    computed = a(p1);
-    expected = a(p2);
-    d1 = assert_computedigits(computed,expected);
-    // Permute both computed and expected with the same permutation p3:
-    // d must not change.
-    p3 = grand(1,"prm",(1:N)');
-    computedP = computed(p3);
-    expectedP = expected(p3);
-    d2 = assert_computedigits(computedP,expectedP);
-    // Apply inverse permutation on d2.
-    pI = permInverse(p3);
-    d2 = d2(pI);
-    assert_checkequal(d1,d2);
-end