trange(1): make start and end values optional parameters - numtools - perform numerical operations on vectors and matrices in unix pipes
 (HTM) git clone git://src.adamsgaard.dk/numtools
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit f5b275d8876246cc06f45727052174755ac0eb17
 (DIR) parent b66c471c38b655c9161c3d3595479fe0e94576dc
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Mon,  2 May 2022 14:04:15 +0200
       
       range(1): make start and end values optional parameters
       
       Diffstat:
         M range.1                             |      33 +++++++++++++++++++++++--------
         M range.c                             |      46 +++++++++++++++++++------------
       
       2 files changed, 53 insertions(+), 26 deletions(-)
       ---
 (DIR) diff --git a/range.1 b/range.1
       t@@ -3,17 +3,21 @@
        .Os
        .Sh NAME
        .Nm range
       -.Nd generates an evenly spaced vector over a spacified range
       +.Nd generates an evenly spaced vector over a range
        .Sh SYNOPSIS
        .Nm
        .Ar cmd
       +.Op Fl b
        .Op Fl e
        .Op Fl f Ar fmtstr
        .Op Fl h
        .Op Fl l
        .Op Fl n Ar num
       -.Ar min_val
       +.Op Fl s
       +.Oo
       +.Op Ar min_val
        .Ar max_val
       +.Oc
        .Sh DESCRIPTION
        .Nm
        generates floating-point numbers that are by default evenly distributed
       t@@ -21,6 +25,12 @@ in the linear, closed interval [
        .Ar min_val
        ,
        .Ar max_val ].
       +If
       +.Ar max_val
       +is not specified, it is 1.
       +If
       +.Ar min_val
       +is not specified, it is 0.
        .Pp
        The options are as follows:
        .Bl -tag -width Ds
       t@@ -49,7 +59,7 @@ When including a format specifier (%..), only use forms that are
        compatible with
        .Vt double
        types.
       -The default format string is '%g'.
       +The default format string is '%g\n'.
        .It Fl h
        Show usage information.
        .It Fl l
       t@@ -58,11 +68,13 @@ and 10^max_val.
        .It Fl n Ar num
        Number of values to produce within the specified range.
        The default is 10.
       +.It Fl s
       +Print the spacing between numbers and exit.
        .El
        .Sh EXAMPLES
       -Generate four equally-spaced numbers in the closed range [0;1]:
       +Generate four equally-spaced numbers in the closed default range [0;1]:
        .Pp
       -.Dl $ range -n 4 0 1
       +.Dl $ range -n 4
        .Dl 0
        .Dl 0.33333
        .Dl 0.66667
       t@@ -72,7 +84,7 @@ 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 $ range -n 4 -f '%.17g\n' 0 1
        .Dl 0
        .Dl 0.33333333333333331
        .Dl 0.66666666666666663
       t@@ -86,14 +98,19 @@ Generate four numbers in the range ]0;1[:
        .Dl 0.6
        .Dl 0.8
        .Pp
       +Print ten numbers in the interval [1;10] with spaces between values:
       +.Pp
       +.Dl $ range -f '%g ' 1 10
       +.Dl 1 2 3 4 5 6 7 8 9 10
       +.Pp
        Repeat and modify a string three times:
        .Pp
       -.Dl $ range -n 3 -f 'The best number is %.0g' 1 3
       +.Dl $ range -n 3 -f 'The best number is %.0g\n' 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:
       +Generate three numbers evenly distributed in logspace from 10^0 to 10^2:
        .Pp
        .Dl $ range -l -n 3 0 2
        .Dl 1
 (DIR) diff --git a/range.c b/range.c
       t@@ -13,16 +13,17 @@ char *argv0;
        static void
        usage(void)
        {
       -        errx(1, "usage: %s [-b] [-e] [-f fmtstr] [-h] [-l] [-n num]"
       -                "min_val max_val\n", argv0);
       +        errx(1, "usage: %s [-b] [-e] [-f fmtstr] [-h] [-l] [-n num] [-s]"
       +                "[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";
       +        int i, ret, n = 10, logrange = 0, openstart = 0, openend = 0,
       +                reportdx = 0;
       +        double minv = 0.0, maxv = 1.0, dx;
       +        char fmtstr[PATH_MAX] = "%g\n";
        
                ARGBEGIN {
                case 'b':
       t@@ -45,25 +46,34 @@ main(int argc, char *argv[])
                case 'n':
                        n = atoi(EARGF(usage()));
                        break;
       +        case 's':
       +                reportdx = 1;
       +                break;
                default:
                        usage();
                } ARGEND;
        
       -        if (argc == 2) {
       +        if (argc > 2)
       +                usage();
       +        else 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();
       +        } else if (argc == 1)
       +                maxv = atof(argv[0]);
       +
       +        dx = (maxv - minv)/(n - 1 + openend + openstart);
       +        if (reportdx) {
       +                printf(fmtstr, dx);
       +                return 0;
       +        }
       +        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);
       +        }
        
                return 0;
        }