projects
/
pspp
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
37ff864
)
expressions: Add support for 2- and 3-operand RND function.
author
Ben Pfaff
<blp@cs.stanford.edu>
Sat, 7 Mar 2015 08:36:42 +0000
(
00:36
-0800)
committer
Ben Pfaff
<blp@cs.stanford.edu>
Sat, 7 Mar 2015 08:36:42 +0000
(
00:36
-0800)
Requested by Tom Smekens.
NEWS
patch
|
blob
|
history
doc/expressions.texi
patch
|
blob
|
history
doc/utilities.texi
patch
|
blob
|
history
src/data/settings.c
patch
|
blob
|
history
src/data/settings.h
patch
|
blob
|
history
src/language/expressions/helpers.c
patch
|
blob
|
history
src/language/expressions/helpers.h
patch
|
blob
|
history
src/language/expressions/operations.def
patch
|
blob
|
history
src/language/utilities/set.q
patch
|
blob
|
history
tests/language/expressions/evaluate.at
patch
|
blob
|
history
diff --git
a/NEWS
b/NEWS
index c1746d6bc89c429588f118c0fec77ab68a5e6040..ed0530656235095bdf155a27f4268f89753b8e74 100644
(file)
--- a/
NEWS
+++ b/
NEWS
@@
-24,6
+24,11
@@
Changes since 0.8.4:
* The GRAPH command is now available. Initially it supports
scatterplots and histograms.
* The GRAPH command is now available. Initially it supports
scatterplots and histograms.
+ * The RND operator in expressions now supports additional operands
+ for rounding 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.
+
Changes from 0.8.3 to 0.8.4:
* Formatting of SYSFILE INFO output was made easier to read.
Changes from 0.8.3 to 0.8.4:
* Formatting of SYSFILE INFO output was made easier to read.
diff --git
a/doc/expressions.texi
b/doc/expressions.texi
index 1570d0dfb437ce72072a677b52898484534395cd..7180bf8793ea24a3c0907c13d70eb3ce1e7ef87e 100644
(file)
--- a/
doc/expressions.texi
+++ b/
doc/expressions.texi
@@
-331,9
+331,13
@@
Returns the remainder when @var{number} is divided by 10. If
@end deftypefn
@cindex rounding
@end deftypefn
@cindex rounding
-@deftypefn {Function} {} RND (@var{number})
-Takes the absolute value of @var{number} and rounds it to an integer.
-Then, if @var{number} was negative originally, negates the result.
+@deftypefn {Function} {} RND (@var{number} [, @var{mult}[, @var{fuzzbits}]])
+Rounds @var{number} and rounds it to a multiple of @var{mult} (by
+default 1). Halves are rounded away from zero, as are values that
+fall short of halves by less than @var{fuzzbits} of errors in the
+least-significant bits of @var{number}. If @var{fuzzbits} is not
+specified then the default is taken from SET FUZZBITS (@pxref{SET
+FUZZBITS}), which is 6 unless overridden.
@end deftypefn
@cindex truncation
@end deftypefn
@cindex truncation
diff --git
a/doc/utilities.texi
b/doc/utilities.texi
index da5b7b0daae7d3f5ae0e99f053b53e2d8c475af2..eb30f892d570444a5036fb963090762b617e720a 100644
(file)
--- a/
doc/utilities.texi
+++ b/
doc/utilities.texi
@@
-440,6
+440,7
@@
SET
/MXLOOPS=@var{max_loops}
/SEED=@{RANDOM,@var{seed_value}@}
/UNDEFINED=@{WARN,NOWARN@}
/MXLOOPS=@var{max_loops}
/SEED=@{RANDOM,@var{seed_value}@}
/UNDEFINED=@{WARN,NOWARN@}
+ /FUZZBITS=@var{fuzzbits}
(data output)
/CC@{A,B,C,D,E@}=@{'@var{npre},@var{pre},@var{suf},@var{nsuf}','@var{npre}.@var{pre}.@var{suf}.@var{nsuf}'@}
(data output)
/CC@{A,B,C,D,E@}=@{'@var{npre},@var{pre},@var{suf},@var{nsuf}','@var{npre}.@var{pre}.@var{suf}.@var{nsuf}'@}
@@
-642,6
+643,13
@@
RANDOM, which will obtain an initial seed from the current time of day.
@item UNDEFINED
Currently not used.
@item UNDEFINED
Currently not used.
+@item FUZZBITS
+@anchor{SET FUZZBITS}
+The maximum number of bits of errors in the least-significant places
+to accept for rounding up a value that is almost halfway between two
+possibilities for rounding with the RND operator (@pxref{Miscellaneous
+Mathematics}). The default @var{fuzzbits} is 6.
+
@item WORKSPACE
The maximum amount of memory (in kilobytes) that @pspp{} will use to store data being processed.
If memory in excess of the workspace size is required, then @pspp{} will start
@item WORKSPACE
The maximum amount of memory (in kilobytes) that @pspp{} will use to store data being processed.
If memory in excess of the workspace size is required, then @pspp{} will start
@@
-878,6
+886,7
@@
SHOW
[DIRECTORY]
[ENVIRONMENT]
[FORMAT]
[DIRECTORY]
[ENVIRONMENT]
[FORMAT]
+ [FUZZBITS]
[LENGTH]
[MXERRS]
[MXLOOPS]
[LENGTH]
[MXERRS]
[MXLOOPS]
diff --git
a/src/data/settings.c
b/src/data/settings.c
index 4c0fde083740ea483852acbaa56e1b53b07dbbb8..5c4e6899b90bd66befbeead94ae40bed2ac64afe 100644
(file)
--- a/
src/data/settings.c
+++ b/
src/data/settings.c
@@
-1,5
+1,5
@@
/* PSPP - a program for statistical analysis.
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011
, 2015
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@
-66,6
+66,7
@@
struct settings
size_t workspace;
struct fmt_spec default_format;
bool testing_mode;
size_t workspace;
struct fmt_spec default_format;
bool testing_mode;
+ int fuzzbits;
int cmd_algorithm;
int global_algorithm;
int cmd_algorithm;
int global_algorithm;
@@
-108,6
+109,7
@@
static struct settings the_settings = {
64L * 1024 * 1024, /* workspace */
{FMT_F, 8, 2}, /* default_format */
false, /* testing_mode */
64L * 1024 * 1024, /* workspace */
{FMT_F, 8, 2}, /* default_format */
false, /* testing_mode */
+ 6, /* fuzzbits */
ENHANCED, /* cmd_algorithm */
ENHANCED, /* global_algorithm */
ENHANCED, /* syntax */
ENHANCED, /* cmd_algorithm */
ENHANCED, /* global_algorithm */
ENHANCED, /* syntax */
@@
-487,6
+489,18
@@
settings_set_testing_mode ( bool testing_mode)
the_settings.testing_mode = testing_mode;
}
the_settings.testing_mode = testing_mode;
}
+int
+settings_get_fuzzbits (void)
+{
+ return the_settings.fuzzbits;
+}
+
+void
+settings_set_fuzzbits (int fuzzbits)
+{
+ the_settings.fuzzbits = fuzzbits;
+}
+
/* Return the current algorithm setting */
enum behavior_mode
settings_get_algorithm (void)
/* Return the current algorithm setting */
enum behavior_mode
settings_get_algorithm (void)
diff --git
a/src/data/settings.h
b/src/data/settings.h
index 409b7fe9ebffb690340dc8ebfbc3f0aca2fb442e..c499293ebb54a49648297af98ce35119295c7b0d 100644
(file)
--- a/
src/data/settings.h
+++ b/
src/data/settings.h
@@
-1,5
+1,5
@@
/* PSPP - a program for statistical analysis.
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2009, 2010
, 2015
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@
-102,6
+102,9
@@
void settings_set_format ( const struct fmt_spec *);
bool settings_get_testing_mode (void);
void settings_set_testing_mode (bool);
bool settings_get_testing_mode (void);
void settings_set_testing_mode (bool);
+int settings_get_fuzzbits (void);
+void settings_set_fuzzbits (int);
+
enum settings_var_style
{
SETTINGS_VAR_STYLE_NAMES,
enum settings_var_style
{
SETTINGS_VAR_STYLE_NAMES,
diff --git
a/src/language/expressions/helpers.c
b/src/language/expressions/helpers.c
index 720d910f686dd6993c9df4d3d19fc9762af9548e..5aad13eb160b5f3f160481fcdaefa30a92b05354 100644
(file)
--- a/
src/language/expressions/helpers.c
+++ b/
src/language/expressions/helpers.c
@@
-1,5
+1,5
@@
/* PSPP - a program for statistical analysis.
/* PSPP - a program for statistical analysis.
- Copyright (C) 2008, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2008, 2010, 2011
, 2015
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@
-661,3
+661,17
@@
npdf_beta (double x, double a, double b, double lambda)
return sum;
}
}
return sum;
}
}
+
+double
+round_nearest (double x, double mult, double fuzzbits)
+{
+ double adjustment;
+
+ if (fuzzbits <= 0)
+ fuzzbits = settings_get_fuzzbits ();
+ adjustment = .5 + exp2 (fuzzbits - DBL_MANT_DIG);
+
+ x /= mult;
+ x = x >= 0. ? floor (x + adjustment) : -floor (-x + adjustment);
+ return x * mult;
+}
diff --git
a/src/language/expressions/helpers.h
b/src/language/expressions/helpers.h
index ef4fdadd4d310c2842fbaba74e0cfec2ef335b91..0d349f7fd9d91510a9f4674336179e44d5d7258d 100644
(file)
--- a/
src/language/expressions/helpers.h
+++ b/
src/language/expressions/helpers.h
@@
-81,4
+81,6
@@
double cdf_bvnor (double x0, double x1, double r);
double idf_fdist (double P, double a, double b);
double idf_fdist (double P, double a, double b);
+double round_nearest (double x, double mult, double fuzzbits);
+
#endif /* expressions/helpers.h */
#endif /* expressions/helpers.h */
diff --git
a/src/language/expressions/operations.def
b/src/language/expressions/operations.def
index 37af54a9118abf8755fd0205cdaebdbe20021f46..60ed2eac2022b863af4ef05dbf34f22452687aa5 100644
(file)
--- a/
src/language/expressions/operations.def
+++ b/
src/language/expressions/operations.def
@@
-1,7
+1,7
@@
// -*- c -*-
//
// PSPP - a program for statistical analysis.
// -*- c -*-
//
// PSPP - a program for statistical analysis.
-// Copyright (C) 2005, 2006, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2009, 2010, 2011, 2012
, 2015
Free Software Foundation, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@
-84,7
+84,9
@@
function LG10(x) = check_errno (log10 (x));
function LN (x) = check_errno (log (x));
function LNGAMMA (x >= 0) = gsl_sf_lngamma (x);
function MOD10 (x) = fmod (x, 10);
function LN (x) = check_errno (log (x));
function LNGAMMA (x >= 0) = gsl_sf_lngamma (x);
function MOD10 (x) = fmod (x, 10);
-function RND (x) = x >= 0. ? floor (x + .5) : -floor (-x + .5);
+function RND (x) = round_nearest (x, 1, 0);
+function RND (x, mult != 0) = round_nearest (x, mult, 0);
+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 SIN (x) = sin (x);
function SQRT (x >= 0) = sqrt (x);
function TAN (x) = check_errno (tan (x));
diff --git
a/src/language/utilities/set.q
b/src/language/utilities/set.q
index f90e3e14de3d8e675b7988879a79c3a2cca83b67..0be8c47010a7cf541501487456e3ba7eae686de8 100644
(file)
--- a/
src/language/utilities/set.q
+++ b/
src/language/utilities/set.q
@@
-1,5
+1,5
@@
/* PSPP - a program for statistical analysis.
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014
, 2015
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@
-80,6
+80,7
@@
int tgetnum (const char *);
epoch=custom;
errors=custom;
format=custom;
epoch=custom;
errors=custom;
format=custom;
+ fuzzbits=integer;
headers=headers:no/yes/blank;
highres=hires:on/off;
histogram=string;
headers=headers:no/yes/blank;
highres=hires:on/off;
histogram=string;
@@
-153,6
+154,14
@@
cmd_set (struct lexer *lexer, struct dataset *ds)
if (cmd.sbc_decimal)
settings_set_decimal_char (cmd.dec == STC_DOT ? '.' : ',');
if (cmd.sbc_decimal)
settings_set_decimal_char (cmd.dec == STC_DOT ? '.' : ',');
+ if (cmd.sbc_fuzzbits)
+ {
+ int fuzzbits = cmd.n_fuzzbits[0];
+ if (fuzzbits >= 0 && fuzzbits <= 20)
+ settings_set_fuzzbits (fuzzbits);
+ else
+ msg (SE, _("%s must be between 0 and 20."), "FUZZBITS");
+ }
if (cmd.sbc_include)
settings_set_include (cmd.inc == STC_ON);
if (cmd.sbc_include)
settings_set_include (cmd.inc == STC_ON);
@@
-710,6
+719,12
@@
show_format (const struct dataset *ds UNUSED)
return xstrdup (fmt_to_string (settings_get_format (), str));
}
return xstrdup (fmt_to_string (settings_get_format (), str));
}
+static char *
+show_fuzzbits (const struct dataset *ds UNUSED)
+{
+ return xasprintf ("%d", settings_get_fuzzbits ());
+}
+
static char *
show_journal (const struct dataset *ds UNUSED)
{
static char *
show_journal (const struct dataset *ds UNUSED)
{
@@
-952,6
+967,7
@@
const struct show_sbc show_table[] =
{"ENVIRONMENT", show_system},
{"ERRORS", show_errors},
{"FORMAT", show_format},
{"ENVIRONMENT", show_system},
{"ERRORS", show_errors},
{"FORMAT", show_format},
+ {"FUZZBITS", show_fuzzbits},
{"JOURNAL", show_journal},
{"LENGTH", show_length},
{"LOCALE", show_locale},
{"JOURNAL", show_journal},
{"LENGTH", show_length},
{"LOCALE", show_locale},
diff --git
a/tests/language/expressions/evaluate.at
b/tests/language/expressions/evaluate.at
index cd514fef93d2455272318b94f78bc311447ed6b3..846eee482b858a3f359df1bfa9685fa7f2050080 100644
(file)
--- a/
tests/language/expressions/evaluate.at
+++ b/
tests/language/expressions/evaluate.at
@@
-334,8
+334,19
@@
CHECK_EXPR_EVAL([exp lg10 ln sqrt abs mod mod10 rnd trunc],
[[rnd(5.6)], [6.00]],
[[rnd(-5.4)], [-5.00]],
[[rnd(-5.6)], [-6.00]],
[[rnd(5.6)], [6.00]],
[[rnd(-5.4)], [-5.00]],
[[rnd(-5.6)], [-6.00]],
+ [[rnd(5.56, .1)], [5.60]],
+ [[rnd(-5.56, .1)], [-5.60]],
+ [[rnd(.5)], [1.00]],
+ [[rnd(.5 - 2**-53)], [1.00]],
+ [[rnd(.5 - 2**-52)], [1.00]],
+ [[rnd(.5 - 2**-51)], [1.00]],
+ [[rnd(.5 - 2**-45)], [0.00]],
+ [[rnd(.5 - 2**-45, 1, 10)], [1.00]],
[[rnd('x')], [error],
[[rnd('x')], [error],
- [error: DEBUG EVALUATE: Type mismatch invoking RND(number) as rnd(string).]],
+ [error: DEBUG EVALUATE: Function invocation rnd(string) does not match any known function. Candidates are:
+RND(number)
+RND(number, number)
+RND(number, number, number).]],
[[trunc(1.2)], [1.00]],
[[trunc(1.9)], [1.00]],
[[trunc(1.2)], [1.00]],
[[trunc(1.9)], [1.00]],