expressions: Add support for mult and fuzzbits arguments to TRUNC function.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2016 19:10:22 +0000 (12:10 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2016 19:10:22 +0000 (12:10 -0700)
NEWS
doc/expressions.texi
src/language/expressions/helpers.c
src/language/expressions/helpers.h
src/language/expressions/operations.def
tests/language/expressions/evaluate.at

diff --git a/NEWS b/NEWS
index bb69e0549017ef9844d62da151216bdcda5bde4c..d280e7f719bc311f5909805a6c41dc391c26dd53 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,11 @@ Changes from 0.8.5 to 0.9.0:
 
    - MEDIAN, to compute the median of its arguments.
 
+   - The TRUNC function in expressions now supports additional arguments
+     for truncating to values other than integers and to indicate a level
+     of rounding fuzz.  The default rounding fuzz may now be controlled
+     and displayed with SET FUZZBITS and SHOW FUZZBITS, respectively.
+
  * Bug fixes, including the following notable ones:
 
    - The correlation coefficient in the paired samples t-test
index 5898d53d77cd0c604666de83b5d171e6c5c8be2a..d27d11b40744a467de4ddcaaf57fccbe55c0ac41 100644 (file)
@@ -342,9 +342,14 @@ FUZZBITS}), which is 6 unless overridden.
 @end deftypefn
 
 @cindex truncation
-@deftypefn {Function} {} TRUNC (@var{number})
-Discards the fractional part of @var{number}; that is, rounds
-@var{number} towards zero.
+@deftypefn {Function} {} TRUNC (@var{number} [, @var{mult}[, @var{fuzzbits}]])
+Rounds @var{number} to a multiple of @var{mult}, toward zero.  For the
+default @var{mult} of 1, this is equivalent to discarding the
+fractional part of @var{number}.  Values that fall short of a multiple
+of @var{mult} by less than @var{fuzzbits} of errors in the
+least-significant bits of @var{number} are rounded away from zero.  If
+@var{fuzzbits} is not specified then the default is taken from SET
+FUZZBITS (@pxref{SET FUZZBITS}), which is 6 unless overridden.
 @end deftypefn
 
 @node Trigonometry
index 57e17713b994f9036c97ddda0d829035fb726605..6e73887285a8d79543b21573ee84d7fc09c415ed 100644 (file)
@@ -665,19 +665,29 @@ npdf_beta (double x, double a, double b, double lambda)
 }
 
 double
-round_nearest (double x, double mult, double fuzzbits)
+round__ (double x, double mult, double fuzzbits, double adjustment)
 {
-  double adjustment;
-
   if (fuzzbits <= 0)
     fuzzbits = settings_get_fuzzbits ();
-  adjustment = .5 + exp2 (fuzzbits - DBL_MANT_DIG);
+  adjustment += exp2 (fuzzbits - DBL_MANT_DIG);
 
   x /= mult;
   x = x >= 0. ? floor (x + adjustment) : -floor (-x + adjustment);
   return x * mult;
 }
 
+double
+round_nearest (double x, double mult, double fuzzbits)
+{
+  return round__ (x, mult, fuzzbits, .5);
+}
+
+double
+round_zero (double x, double mult, double fuzzbits)
+{
+  return round__ (x, mult, fuzzbits, 0);
+}
+
 struct substring
 replace_string (struct expression *e,
                 struct substring haystack,
index c4e332340625f17d9f52962b743eaa00c11efb9e..8646233b66814338c57def027912d5d718243038 100644 (file)
@@ -82,6 +82,7 @@ double cdf_bvnor (double x0, double x1, double r);
 double idf_fdist (double P, double a, double b);
 
 double round_nearest (double x, double mult, double fuzzbits);
+double round_zero (double x, double mult, double fuzzbits);
 
 struct substring replace_string (struct expression *,
                                  struct substring haystack,
index eb05661678277fb8cc25233d91beda496bd063bf..e8f1f781dc29d3bbc0042e55cce0fec3f81f5c1c 100644 (file)
@@ -90,7 +90,9 @@ function RND (x, mult != 0, fuzzbits >= 0) = round_nearest (x, mult, fuzzbits);
 function SIN (x) = sin (x);
 function SQRT (x >= 0) = sqrt (x);
 function TAN (x) = check_errno (tan (x));
-function TRUNC (x) = x >= 0. ? floor (x) : -floor (-x);
+function TRUNC (x) = round_zero (x, 1, 0);
+function TRUNC (x, mult != 0) = round_zero (x, mult, 0);
+function TRUNC (x, mult != 0, fuzzbits >= 0) = round_zero (x, mult, fuzzbits);
 
 absorb_miss function MOD (n, d)
 {
index ae7c89a5bb5335a1b519748ce8547ea71345dde8..15641d6073f5ae39e1d7d4b54cdf06d82f34fd1d 100644 (file)
@@ -352,8 +352,19 @@ RND(number, number, number).]],
   [[trunc(1.9)], [1.00]],
   [[trunc(-1.2)], [-1.00]],
   [[trunc(-1.9)], [-1.00]],
+  [[trunc(5.06, .1)], [5.00]],
+  [[trunc(-5.06, .1)], [-5.00]],
+  [[trunc(1)], [1.00]],
+  [[trunc(1 - 2**-53)], [1.00]],
+  [[trunc(1 - 2**-52)], [1.00]],
+  [[trunc(1 - 2**-51)], [1.00]],
+  [[trunc(1 - 2**-45)], [0.00]],
+  [[trunc(1 - 2**-45, 1, 10)], [1.00]],
   [[trunc('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking TRUNC(number) as trunc(string).]])
+   [error: DEBUG EVALUATE: Function invocation trunc(string) does not match any known function.  Candidates are:
+TRUNC(number)
+TRUNC(number, number)
+TRUNC(number, number, number).]])
 
 CHECK_EXPR_EVAL([acos arsin artan cos sin tan],
   [[acos(.5) / 3.14159 * 180], [60.00]],