[Nickle] nickle: Branch 'master' - 10 commits
Keith Packard
keithp at keithp.com
Thu Sep 17 15:07:36 PDT 2009
.gitignore | 9 +++
Makefile.am | 3 -
configure.in | 2
debian/changelog | 14 ++++-
debian/compat | 2
debian/control | 6 +-
debian/rules | 2
math.5c | 83 +++++++++++++++---------------
test/Makefile.am | 14 ++++-
test/math-tables.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++
test/math.5c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 356 insertions(+), 51 deletions(-)
New commits:
commit 4c6a840a3f2596bf6565f1b9906b2500852b66c6
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 15:03:12 2009 -0700
Update to version 2.69
diff --git a/configure.in b/configure.in
index 95fe2e3..81fd8a6 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ dnl for licensing information.
AC_PREREQ(2.59)
AC_INIT([nickle],
- 2.68,
+ 2.69,
[http://nickle.org],
nickle)
diff --git a/debian/changelog b/debian/changelog
index fc12f97..6d0e977 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+nickle (2.69-1) unstable; urgency=low
+
+ * Make debian build epend on libreadline-dev not libreadline5-dev.
+ * Get math-tables.5c built before tests are run
+ * Fix trig boundary conditions.
+ * Add tests for math functions.
+ * math.5c: fix quadrant errors in atan/asin/acos
+
+ -- Keith Packard <keithp at keithp.com> Thu, 17 Sep 2009 14:30:42 -0700
+
nickle (2.68-1) unstable; urgency=low
* Add README.release
@@ -22,7 +32,7 @@ nickle (2.67-1) unstable; urgency=low
nickle (2.66-1) unstable; urgency=low
* Support autoload/autoimport of nested namespaces.
* Allow 'print' to find unpublished names
-
+
-- Keith Packard <keithp at keithp.com> Sun, 13 Jan 2008 17:39:49 -0800
nickle (2.65-1) unstable; urgency=low
@@ -31,7 +41,7 @@ nickle (2.65-1) unstable; urgency=low
* Check for duplicate func param/struct member names
-- Keith Packard <keithp at keithp.com> Sun, 06 Jan 2008 16:38:51 -0800
-
+
nickle (2.64-1) unstable; urgency=low
* Fix float floor/ceil with small values
* Copy hash key/value on insert
commit eaf3950ad5308e33a5dbfd8b1c921ae2603fd5c5
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 14:59:31 2009 -0700
Update to standards 3.8.3 and debhelper 7
diff --git a/debian/compat b/debian/compat
index b8626c4..7f8f011 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-4
+7
diff --git a/debian/control b/debian/control
index bec3cb3..9d8f7e5 100644
--- a/debian/control
+++ b/debian/control
@@ -2,12 +2,12 @@ Source: nickle
Section: interpreters
Priority: optional
Maintainer: Keith Packard <keithp at keithp.com>
-Build-Depends: debhelper (>= 4), libreadline-dev
-Standards-Version: 3.8.0
+Build-Depends: debhelper (>= 7), libreadline-dev
+Standards-Version: 3.8.3
Package: nickle
Architecture: any
-Depends: ${shlibs:Depends} ${misc:Depends}
+Depends: ${shlibs:Depends}, ${misc:Depends}
Description: desk calculator language
Nickle is a language with powerful programming and scripting capabilities.
Nickle supports a variety of datatypes, especially arbitrary precision
diff --git a/debian/rules b/debian/rules
index e53b769..a24c3fd 100755
--- a/debian/rules
+++ b/debian/rules
@@ -28,7 +28,7 @@ clean:
install: build
dh_testdir
dh_testroot
- dh_clean -k
+ dh_prep
dh_installdirs
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
pwd
commit b9bae75689465f0572deed07d0514f546648d32a
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 14:58:49 2009 -0700
Remove debian dir from debian orig.tar.gz file
diff --git a/Makefile.am b/Makefile.am
index 4d1cf69..7611173 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -110,6 +110,7 @@ $(DEB_TAR): $(TARFILE)
rm -rf $(DEB_TAR_DIR)
tar xzf $(TARFILE)
mv $(distdir) $(DEB_TAR_DIR)
+ rm -rf $(DEB_TAR_DIR)/debian
tar czf $(DEB_TAR) $(DEB_TAR_DIR)
nickle.1: nickle.1.in config.h
commit bb5e73b56f322a04d914f48856d72c4d00626214
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 14:39:48 2009 -0700
Ignore more files
diff --git a/.gitignore b/.gitignore
index 0ec1e2d..d3d90bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,12 @@ version-sh
nickle-[1-9].*
nickle_[1-9].*
nickle
+ChangeLog
+build-stamp
+configure-stamp
+debian/files
+debian/nickle.debhelper.log
+debian/nickle.substvars
+test/math-tables
+test/math-tables.5c
+ylwrap
commit a85c4aba193b67294c8bafeec24ce7c2b32ea75c
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 14:28:30 2009 -0700
Byacc now makes tables const by default. Remove Makefile.am hacks.
The Makefile.am hacks served to turn the parser tables into constant
data to save a bit of memory. That's no longer necessary now that
byacc does this automatically.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/Makefile.am b/Makefile.am
index 168115e..4d1cf69 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -85,8 +85,6 @@ USES_GRAM_H = \
$(USES_GRAM_H): gram.h
-YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) && sed -i 's/^short yy/static const short yy/' y.tab.c && echo
-
builtin.o main.o: Makefile
TARFILE=$(PACKAGE)-$(VERSION).tar.gz
commit fb02b3053b9615b6872352fa0581ee68d047b625
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 11:56:09 2009 -0700
Make debian build epend on libreadline-dev not libreadline5-dev.
This ensures that we'll pick up any new readline versions as released.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/debian/control b/debian/control
index 64bf0c3..bec3cb3 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@ Source: nickle
Section: interpreters
Priority: optional
Maintainer: Keith Packard <keithp at keithp.com>
-Build-Depends: debhelper (>= 4), libreadline5-dev
+Build-Depends: debhelper (>= 4), libreadline-dev
Standards-Version: 3.8.0
Package: nickle
commit ac6bdfab92361bc999323e1f4bb1fa022527fd16
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 10:20:11 2009 -0700
Get math-tables.5c built before tests are run
This file is used by math.5c and is built by running the math-tables
program; adding a dependency from math.5c appears to make sure it is
built at the right time.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index 5e12384..96e9f89 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -14,13 +14,14 @@ noinst_PROGRAMS=math-tables
TABLES=math-tables.5c
+CLEANFILES=$(TABLES)
+
TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir) ../nickle
TESTS=$(check_SCRIPTS)
EXTRA_DIST=$(check_SCRIPTS)
+math.5c: $(TABLES)
+
$(TABLES): math-tables
./math-tables > $(TABLES)
-
-
-check-TESTS: math-tables.5c
commit 0a80c1f7816a19970a0751af5baaaf0643f68bdd
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 10:00:11 2009 -0700
Fix trig boundary conditions.
limit angles to -Ï - Ï, make sincos generate correct signs, make
atan2(0,0) return 0.
diff --git a/math.5c b/math.5c
index 0bebd2e..a6cd170 100644
--- a/math.5c
+++ b/math.5c
@@ -37,6 +37,9 @@ extend namespace Math {
return abs (1/cur);
}
+ if (v == 0)
+ return 0;
+
if (is_rational (v))
{
int num, den;
@@ -544,15 +547,17 @@ extend namespace Math {
return imprecise (local_pi, prec);
}
+ /* Normalize angle to -Ï < aa <= Ï */
real limit_angle_to_pi (real aa)
{
real my_pi;
aa = imprecise (aa);
my_pi = pi_value (precision (aa));
+ aa %= 2 * my_pi;
if (aa > my_pi)
- aa = aa - 2 * my_pi;
- return aa % (2 * my_pi);
+ aa -= 2 * my_pi;
+ return aa;
}
public real sin (real a)
@@ -690,7 +695,7 @@ extend namespace Math {
a = limit_angle_to_pi (a);
c = cos (a);
- s = sign(a) * abs (cos_to_sin(c));
+ s = sign(a) * cos_to_sin(c);
*cosp = c;
*sinp = s;
}
@@ -702,7 +707,7 @@ extend namespace Math {
{
real c, s;
- a = imprecise (a);
+ a = imprecise(a);
sin_cos (a, &s, &c);
return s/c;
}
@@ -783,6 +788,8 @@ extend namespace Math {
x = imprecise (x);
if (x == 0) {
+ if (y == 0)
+ return 0;
if (y >= 0)
return pi_value(precision(y))/2;
else
commit 8aa40d0d867bcfe8b917c49b7d36138c835130c2
Author: Keith Packard <keithp at keithp.com>
Date: Thu Sep 17 09:58:56 2009 -0700
Add tests for math functions.
These compare the results of nickle with the C library math functions
to provide a rough check of correctness as well as checking various
boundary conditions for the functions.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index f3d78e4..5e12384 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -7,9 +7,20 @@ check_SCRIPTS=gcdtest.5c \
modtest.5c \
hashtest.5c \
signal.5c \
- round.5c
+ round.5c \
+ math.5c
+
+noinst_PROGRAMS=math-tables
+
+TABLES=math-tables.5c
TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir) ../nickle
TESTS=$(check_SCRIPTS)
EXTRA_DIST=$(check_SCRIPTS)
+
+$(TABLES): math-tables
+ ./math-tables > $(TABLES)
+
+
+check-TESTS: math-tables.5c
diff --git a/test/math-tables.c b/test/math-tables.c
new file mode 100644
index 0000000..129c989
--- /dev/null
+++ b/test/math-tables.c
@@ -0,0 +1,129 @@
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define FMT "%25.17f"
+
+double
+print_val(double x)
+{
+ if (isnan(x))
+ return 10000;
+ if (x > 1e10)
+ return 9999;
+ if (x < -1e10)
+ return 9999;
+ if (fabs(x) < 1e-20)
+ return 0;
+ return x;
+}
+
+static void
+sin_cos_table(void)
+{
+ double a;
+ double r;
+
+ printf ("/* %20.15f */\n", asin(-1));
+ printf ("typedef struct { real angle, sin, cos; } sin_cos_t;\n");
+ printf ("sin_cos_t[] sin_cos_table = {\n");
+ for (a = -800; a <= 800; a += 1) {
+ double a_f = a / 100;
+ printf ("\t{ .angle = " FMT ", .sin = " FMT ", .cos = " FMT " },\n",
+ a_f, print_val(sin(a_f)), print_val(cos(a_f)));
+ printf ("\t{ .angle = Ï * " FMT ", .sin = " FMT ", .cos = " FMT " },\n",
+ a_f, print_val(sin(M_PI * a_f)), print_val(cos(M_PI * a_f)));
+ }
+ printf ("};\n");
+
+ printf ("typedef struct { real ratio, asin, acos; } asin_acos_t;\n");
+ printf ("asin_acos_t[] asin_acos_table = {\n");
+ for (r = -200; r <= 200; r += 1) {
+ double r_f = r / 100;
+ printf ("\t{ .ratio = " FMT ", .asin = " FMT ", .acos = " FMT " },\n",
+ r_f, print_val(asin(r_f)), print_val(acos(r_f)));
+ }
+ printf ("};\n");
+}
+
+static void
+tan_table(void)
+{
+ double a;
+ double r;
+ double x, y;
+
+ printf ("typedef struct { real angle, tan; } tan_t;\n");
+ printf ("tan_t[] tan_table = {\n");
+ for (a = -800; a <= 800; a += 1) {
+ double a_f = a/100;
+ printf ("\t{ .angle = " FMT ", .tan = " FMT " },\n",
+ a_f, print_val(tan(a_f)));
+ printf ("\t{ .angle = Ï * " FMT ", .tan = " FMT " },\n",
+ a_f, print_val(tan(M_PI * a_f)));
+ }
+ printf ("};\n");
+
+ printf ("typedef struct { real ratio, atan; } atan_t;\n");
+ printf ("atan_t[] atan_table = {\n");
+ for (r = -1000; r <= 1000; r += 1) {
+ double r_f = r / 10;
+ printf ("\t{ .ratio = " FMT ", .atan = " FMT " },\n",
+ r_f, print_val(atan(r_f)));
+ }
+ printf ("};\n");
+
+ printf ("typedef struct { real y, x, atan2; } atan2_t;\n");
+ printf ("atan2_t[] atan2_table = {\n");
+ for (y = -30; y <= 30; y += 1) {
+ double y_f = y / 10;
+ for (x = -30; x <= 30; x += 1) {
+ double x_f = x/10;
+ double v;
+
+ /*
+ * looks like glibc has a bug -- atan2(0,0) returns
+ * Ï/4 instead of 0
+ */
+ if (y_f == 0 && x_f == 0)
+ v = 0;
+ else
+ v = atan2(y_f,x_f);
+
+ printf ("\t{ .y = " FMT ", .x = " FMT ", .atan2 = " FMT " },\n",
+ y_f, x_f, print_val(v));
+ }
+ }
+ printf ("};\n");
+}
+
+void
+log_table(void)
+{
+ double v;
+ printf ("typedef struct { real in, log; } log_t;\n");
+ printf ("log_t[] log_table = {\n");
+ for (v = 1; v < 1e20; v *= 2) {
+ double v_f = v/1e6;
+ printf("\t{ .in = " FMT ", .log = " FMT " },\n",
+ v_f, log(v_f));
+ }
+ printf ("};\n");
+ printf ("typedef struct { real in, exp; } exp_t;\n");
+ printf ("exp_t[] exp_table = {\n");
+ for (v = -1000; v < 1000; v += 1) {
+ double v_f = v/100;
+ printf("\t{ .in = " FMT ", .exp = " FMT " },\n",
+ v_f, exp(v_f));
+ }
+ printf ("};\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ sin_cos_table();
+ tan_table();
+ log_table();
+ exit(0);
+}
diff --git a/test/math.5c b/test/math.5c
new file mode 100644
index 0000000..902f03b
--- /dev/null
+++ b/test/math.5c
@@ -0,0 +1,143 @@
+/*
+ * Nickle test suite
+ *
+ * Trig operator tests
+ */
+
+load "math-tables.5c"
+
+int precision = 64;
+int errors = 0;
+
+real checked(real(real) f, real a) {
+ try {
+ real r = f(imprecise (a, precision));
+ if (r > 1e10)
+ return 9999;
+ if (r < -1e10)
+ return 9999;
+ return r;
+ } catch invalid_argument(string type, int i, real v) {
+ return 10000;
+ }
+ return 0;
+}
+
+real checked2(real(real, real) f, real a, real b) {
+ try {
+ real r = f(imprecise(a, precision), imprecise(b, precision));
+
+ /* Just return the same value for large magnitudes
+ * as small variations in input cause the sign to flip
+ */
+
+ if (r > 1e10)
+ return 9999;
+ if (r < -1e10)
+ return 9999;
+ return r;
+ } catch invalid_argument(string type, int i, real v) {
+ return 10000;
+ }
+ return 0;
+}
+
+void check(string op, real(real) f, real input, real correct)
+{
+ real value = checked(f, input);
+
+ if (is_number (value))
+ {
+ real error = abs (value - correct);
+
+ if (abs(correct) >= 1 && error < abs(correct) * 1e-8)
+ return;
+ if (abs(correct) < 1 && error < 1e-8)
+ return;
+ printf ("error %v value %v\n", error, value);
+ }
+ if (value != correct) {
+ printf ("check failed %s(%v) (was %.-g, should be %.-g)",
+ op, input, value, correct);
+ errors++;
+ }
+}
+
+void check2(string op, real(real, real) f, real input1, real input2, real correct)
+{
+ real value = checked2(f, input1, input2);
+
+ if (is_number (value))
+ {
+ real error = abs (value - correct);
+
+ if (abs(correct) >= 1 && error < abs(correct) * 1e-10)
+ return;
+ if (abs(correct) < 1 && error < 1e-10)
+ return;
+ printf ("error %v value %v\n", error, value);
+ }
+ if (value != correct) {
+ printf ("check failed %s(%.-g, %.-g) (was %.-g, should be %.-g)",
+ op, input1, input2, value, correct);
+ errors++;
+ }
+}
+
+void check_sin_cos()
+{
+ for (int i = 0; i < dim(sin_cos_table); i++) {
+ real angle = sin_cos_table[i].angle;
+ real sin_value = sin_cos_table[i].sin;
+ real cos_value = sin_cos_table[i].cos;
+ check("sin", sin, angle, sin_value);
+ check("cos", cos, angle, cos_value);
+ }
+ for (int i = 0; i < dim(asin_acos_table); i++) {
+ real ratio = asin_acos_table[i].ratio;
+ real asin_value = asin_acos_table[i].asin;
+ real acos_value = asin_acos_table[i].acos;
+ check("asin", asin, ratio, asin_value);
+ check("acos", acos, ratio, acos_value);
+ }
+}
+
+void check_tan()
+{
+ for (int i = 0; i < dim(tan_table); i++) {
+ real angle = tan_table[i].angle;
+ real tan_value = tan_table[i].tan;
+ check("tan", tan, angle, tan_value);
+ }
+ for (int i = 0; i < dim(atan_table); i++) {
+ real ratio = atan_table[i].ratio;
+ real atan_value = atan_table[i].atan;
+ check("atan", atan, ratio, atan_value);
+ }
+ for (int i = 0; i < dim(atan2_table); i++) {
+ real y = atan2_table[i].y;
+ real x = atan2_table[i].x;
+ real atan2_value = atan2_table[i].atan2;
+ check2("atan2", atan2, y, x, atan2_value);
+ }
+}
+
+void check_log()
+{
+ for (int i = 0; i < dim(log_table); i++) {
+ real in = log_table[i].in;
+ real log_value = log_table[i].log;
+ check("log", log, in, log_value);
+ }
+ for (int i = 0; i < dim(exp_table); i++) {
+ real in = exp_table[i].in;
+ real exp_value = exp_table[i].exp;
+ check("exp", exp, in, exp_value);
+ }
+}
+
+check_sin_cos();
+check_tan();
+check_log();
+
+exit (errors);
commit cab93dd5f5a04ce53bf826d9a0e5e8063bd293a6
Author: Keith Packard <keithp at keithp.com>
Date: Sun Jun 14 17:27:16 2009 -0700
math.5c: fix quadrant errors in atan/asin/acos
All of these had various quadrant related errors.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/math.5c b/math.5c
index 16993df..0bebd2e 100644
--- a/math.5c
+++ b/math.5c
@@ -772,6 +772,34 @@ extend namespace Math {
}
/*
+ * atan (y/x)
+ */
+ public real atan2 (real y, real x)
+ /*
+ * return atan (y/x), but adjust for quadrant correctly
+ */
+ {
+ y = imprecise (y);
+ x = imprecise (x);
+
+ if (x == 0) {
+ if (y >= 0)
+ return pi_value(precision(y))/2;
+ else
+ return -pi_value(precision(y))/2;
+ }
+ real a = atan(y/x);
+ if (x < 0) {
+ real p = pi_value(precision(y));
+ if (y >= 0)
+ a += p;
+ else
+ a -= p;
+ }
+ return a;
+ }
+
+ /*
* atan(v) = asin(v/sqrt(1+v**2))
*
* q = v/sqrt(1+v**2)
@@ -783,7 +811,7 @@ extend namespace Math {
* v**2 = q**2/(1-q**2)
* v = q/sqrt(1-q**2)
*
- * asin(q) = atan(q/sqrt(1-q**2))
+ * asin(q) = atan2(q, sqrt(1-q**2))
*/
public real asin (real v)
@@ -798,14 +826,14 @@ extend namespace Math {
return pi_value (precision (v))/2;
if (v == -1)
return -pi_value (precision (v))/2;
- return atan (v/sqrt(1-v**2));
+ return atan2(v, sqrt(1-v**2));
}
/*
* acos(v) = asin (sqrt (1 - v**2))
* = atan (sqrt(1-v**2) / sqrt (1-(sqrt (1-v**2))**2))
* = atan (sqrt(1-v**2) / sqrt (1-(1-v**2)))
- * = atan (sqrt(1-v**2) / v)
+ * = atan2 (sqrt(1-v**2), v)
*/
public real acos (real v)
/*
@@ -821,42 +849,10 @@ extend namespace Math {
return pi_value(precision(v));
if (v == 0)
return pi_value(precision(v))/2;
- return atan (sqrt (1-v**2)/v);
+ return atan2 (sqrt (1-v**2), v);
}
/*
- * atan (y/x)
- */
- public real atan2 (real y, real x)
- /*
- * return atan (y/x), but adjust for quadrant correctly
- */
- {
- y = imprecise (y);
- x = imprecise (x);
- if (y == 0)
- {
- if (x >= 0)
- return 0;
- return pi_value (precision (y));
- }
- if (x == 0)
- return sign(y) * pi_value (precision (y))/2;
-
- real a;
-
- a = atan (y/x);
- if (x < 0)
- {
- if (y >= 0)
- a += pi_value (precision (a));
- else
- a -= pi_value (precision (a));
- }
- return a;
- }
-
- /*
* These two are used for the '**' and '**=' operators
*/
public real pow (real a, real b)
More information about the Nickle
mailing list