commit b6731286f9cd7efd11eafb989f04acb26edd696e
parent 2e9d87b259dcacf7c74ce8ca85554b05d08533d0
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date: Mon, 2 May 2022 13:33:30 +0200
add range(1) tool
Diffstat:
M | Makefile | | | 6 | ++++-- |
A | range.1 | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | range.c | | | 69 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | rangetest.1 | | | 1 | + |
4 files changed, 183 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
.POSIX:
NAME = mathtools
-VERSION = 0.2.5
+VERSION = 0.2.6
# paths
PREFIX = /usr/local
@@ -12,6 +12,7 @@ BIN =\
max\
mean\
min\
+ range\
rangetest\
sum\
transpose\
@@ -54,6 +55,7 @@ ${OBJ}: ${HDR}
max: max.o
mean: mean.o
min: min.o
+range: range.o
rangetest: rangetest.o
sum: sum.o
transpose: transpose.o
@@ -64,7 +66,7 @@ ${BIN}: ${LIB} ${OBJ}
.c.o:
${CC} ${_CFLAGS} ${_CPPFLAGS} -o $@ -c $<
-install:
+install:
# installing executable files and scripts.
mkdir -p "${DESTDIR}${PREFIX}/bin"
cp -f ${BIN} ${SCRIPTS} "${DESTDIR}${PREFIX}/bin"
diff --git a/range.1 b/range.1
@@ -0,0 +1,109 @@
+.Dd $Mdocdate$
+.Dt RANGE 1
+.Os
+.Sh NAME
+.Nm range
+.Nd generates an evenly spaced vector over a spacified range
+.Sh SYNOPSIS
+.Nm
+.Ar cmd
+.Op Fl e
+.Op Fl f Ar fmtstr
+.Op Fl h
+.Op Fl l
+.Op Fl n Ar num
+.Ar min_val
+.Ar max_val
+.Sh DESCRIPTION
+.Nm
+generates floating-point numbers that are by default evenly distributed
+in the linear, closed interval [
+.Ar min_val
+,
+.Ar max_val ].
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl b
+Do not include
+.Ar min_val
+as the first value, making it a half-open interval ]
+.Ar min_val
+,
+.Ar max_val ],
+or an entirely open interval when combined with
+.Ar e .
+.It Fl e
+Do not include
+.Ar max_val
+as the last value, making it a half-open interval [
+.Ar min_val
+,
+.Ar max_val [,
+or an entirely open interval when combined with
+.Ar b .
+.It Fl f Ar fmtstr
+Formatting string to use as documented in
+.Xr printf 3 .
+When including a format specifier (%..), only use forms that are
+compatible with
+.Vt double
+types.
+The default format string is '%g'.
+.It Fl h
+Show usage information.
+.It Fl l
+Produce output with even intervals in logarithmic space between 10^min_val
+and 10^max_val.
+.It Fl n Ar num
+Number of values to produce within the specified range.
+The default is 10.
+.El
+.Sh EXAMPLES
+Generate four equally-spaced numbers in the closed range [0;1]:
+.Pp
+.Dl $ range -n 4 0 1
+.Dl 0
+.Dl 0.33333
+.Dl 0.66667
+.Dl 1
+.Pp
+Same as the previous example, but with full
+.Vt double
+precision on a 64-bit system:
+.Pp
+.Dl $ range -n 4 -f '%.17g' 0 1
+.Dl 0
+.Dl 0.33333333333333331
+.Dl 0.66666666666666663
+.Dl 1
+.Pp
+Generate four numbers in the range ]0;1[:
+.Pp
+.Dl $ range -b -e -n 4 0 1
+.Dl 0.2
+.Dl 0.4
+.Dl 0.6
+.Dl 0.8
+.Pp
+Repeat and modify a string three times:
+.Pp
+.Dl $ range -n 3 -f 'The best number is %.0g' 1 3
+.Dl The best number is 1
+.Dl The best number is 2
+.Dl The best number is 3
+.Pp
+Generate three numbers evenly distributed in logspace from 10^0 to 10^3:
+.Pp
+.Dl $ range -l -n 3 0 2
+.Dl 1
+.Dl 10
+.Dl 100
+.Sh SEE ALSO
+.Xr max 1 ,
+.Xr mean 1 ,
+.Xr min 1 ,
+.Xr rangetest 1 ,
+.Xr sum 1
+.Sh AUTHORS
+.An Anders Damsgaard Aq Mt anders@adamsgaard.dk
diff --git a/range.c b/range.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+#include <limits.h>
+#include <string.h>
+#include <math.h>
+
+#include "arg.h"
+#include "util.h"
+
+char *argv0;
+
+static void
+usage(void)
+{
+ errx(1, "usage: %s [-b] [-e] [-f fmtstr] [-h] [-l] [-n num]"
+ "min_val max_val\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int i, ret, n = 10, logrange = 0, openstart = 0, openend = 0;
+ double minv, maxv, dx;
+ char fmtstr[PATH_MAX] = "%g";
+
+ ARGBEGIN {
+ case 'b':
+ openstart = 1;
+ break;
+ case 'e':
+ openend = 1;
+ break;
+ case 'f':
+ ret = snprintf(fmtstr, sizeof(fmtstr), "%s", EARGF(usage()));
+ if (ret < 0 || (size_t)ret >= sizeof(fmtstr))
+ errx(1, "%s: could not write fmtstr", __func__);
+ break;
+ case 'h':
+ usage();
+ break;
+ case 'l':
+ logrange = 1;
+ break;
+ case 'n':
+ n = atoi(EARGF(usage()));
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc == 2) {
+ minv = atof(argv[0]);
+ maxv = atof(argv[1]);
+ dx = (maxv - minv)/(n - 1 + openend + openstart);
+ if (minv >= maxv)
+ errx(1, "min_val must be smaller than max_val");
+ for (i = 0 + openstart; i < n + openstart; i++) {
+ if (logrange)
+ printf(fmtstr, pow(10, minv + i * dx));
+ else
+ printf(fmtstr, minv + i * dx);
+ putchar('\n');
+ }
+ } else
+ usage();
+
+ return 0;
+}
diff --git a/rangetest.1 b/rangetest.1
@@ -94,6 +94,7 @@ while surpressing its output:
.Xr max 1 ,
.Xr mean 1 ,
.Xr min 1 ,
+.Xr range 1 ,
.Xr sum 1
.Sh AUTHORS
.An Anders Damsgaard Aq Mt anders@adamsgaard.dk