From 38b4c167efba97445e3dffca780ccab4a3b7937a Mon Sep 17 00:00:00 2001 From: rin Date: Sat, 11 Nov 2017 23:48:44 +0000 Subject: Add -h option to factor(6): duplicate factors are printed in "human-readable" form of x^n. --- factor/factor.6 | 25 ++++++++++++++++++++----- factor/factor.c | 50 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 20 deletions(-) (limited to 'factor') diff --git a/factor/factor.6 b/factor/factor.6 index c36fcb1f..d8c6df26 100644 --- a/factor/factor.6 +++ b/factor/factor.6 @@ -1,4 +1,4 @@ -.\" $NetBSD: factor.6,v 1.13 2014/10/02 21:36:37 ast Exp $ +.\" $NetBSD: factor.6,v 1.14 2017/11/11 23:48:44 rin Exp $ .\" .\" Copyright (c) 1989, 1993 .\" The Regents of the University of California. All rights reserved. @@ -35,7 +35,7 @@ .\" .\" By Landon Curt Noll, http://www.isthe.com/chongo/index.html /\oo/\ .\" -.Dd May 15, 2010 +.Dd Nov 12, 2017 .Dt FACTOR 6 .Os .Sh NAME @@ -43,6 +43,7 @@ .Nd factor a number .Sh SYNOPSIS .Nm +.Op Fl h .Op Ar number ... .Sh DESCRIPTION The @@ -54,15 +55,20 @@ and the list of .Pq prime factors on a single line. Factors are listed in ascending order, and are preceded by a space. -If a factor divides a value more than once, it will be printed more than once. +By default, if a factor divides a value more than once, it will be +printed more than once. .Pp When .Nm -is invoked with one or more arguments, each argument will be factored. +is invoked with one or more +.Ar number +arguments, each argument will be factored. .Pp When .Nm -is invoked with no arguments, +is invoked with no +.Ar number +arguments, .Nm reads numbers, one per line, from standard input, until end of file or error. Leading white-space and empty lines are ignored. @@ -84,6 +90,15 @@ If .Nm is compiled without OpenSSL it is limited to the maximum value of .Vt unsigned long . +.Pp +The following option is available: +.Bl -tag -width flag +.It Fl h +If the +.Fl h +flag is specified, factors will be printed in "human-readable" format. +If a factor x divides a value n (>1) times, it will appear as x^n. +.El .Sh DIAGNOSTICS Out of range or invalid input results in an appropriate error message to standard error. diff --git a/factor/factor.c b/factor/factor.c index 0af41a14..ac8233ce 100644 --- a/factor/factor.c +++ b/factor/factor.c @@ -1,4 +1,4 @@ -/* $NetBSD: factor.c,v 1.27 2014/10/02 21:36:37 ast Exp $ */ +/* $NetBSD: factor.c,v 1.28 2017/11/11 23:48:44 rin Exp $ */ /* * Copyright (c) 1989, 1993 @@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1993\ #if 0 static char sccsid[] = "@(#)factor.c 8.4 (Berkeley) 5/4/95"; #else -__RCSID("$NetBSD: factor.c,v 1.27 2014/10/02 21:36:37 ast Exp $"); +__RCSID("$NetBSD: factor.c,v 1.28 2017/11/11 23:48:44 rin Exp $"); #endif #endif /* not lint */ @@ -52,15 +52,18 @@ __RCSID("$NetBSD: factor.c,v 1.27 2014/10/02 21:36:37 ast Exp $"); * By Landon Curt Noll, http://www.isthe.com/chongo/index.html /\oo/\ * * usage: - * factor [number] ... + * factor [-h] [number] ... * - * The form of the output is: + * By Default, the form of the output is: * * number: factor1 factor1 factor2 factor3 factor3 factor3 ... * * where factor1 <= factor2 <= factor3 <= ... * - * If no args are given, the list of numbers are read from stdin. + * If the -h flag is specified, the output is in "human-readable" format. + * Duplicate factors are printed in the form of x^n. + * + * If no number args are given, the list of numbers are read from stdin. */ #include @@ -103,7 +106,7 @@ static int BN_dec2bn(BIGNUM **a, const char *str); static BN_CTX *ctx; /* just use a global context */ #endif -static void pr_fact(BIGNUM *); /* print factors of a value */ +static void pr_fact(BIGNUM *, int); /* print factors of a value */ static void BN_print_dec_fp(FILE *, const BIGNUM *); static void usage(void) __dead; #ifdef HAVE_OPENSSL @@ -132,7 +135,7 @@ int main(int argc, char *argv[]) { BIGNUM *val; - int ch; + int ch, hflag; char *p, buf[LINE_MAX]; /* > max number of digits. */ #ifdef HAVE_OPENSSL @@ -142,8 +145,12 @@ main(int argc, char *argv[]) if (val == NULL) errx(1, "can't initialise bignum"); - while ((ch = getopt(argc, argv, "")) != -1) + hflag = 0; + while ((ch = getopt(argc, argv, "h")) != -1) switch (ch) { + case 'h': + hflag = 1; + break; case '?': default: usage(); @@ -166,7 +173,7 @@ main(int argc, char *argv[]) errx(1, "negative numbers aren't permitted."); if (BN_dec2bn(&val, buf) == 0) errx(1, "%s: illegal numeric format.", argv[0]); - pr_fact(val); + pr_fact(val, hflag); } /* Factor the arguments. */ else @@ -175,7 +182,7 @@ main(int argc, char *argv[]) errx(1, "numbers <= 1 aren't permitted."); if (BN_dec2bn(&val, argv[0]) == 0) errx(1, "%s: illegal numeric format.", argv[0]); - pr_fact(val); + pr_fact(val, hflag); } exit(0); } @@ -188,15 +195,19 @@ main(int argc, char *argv[]) * processing. * * Print the factors of the number, from the lowest to the highest. - * A factor will be printed numtiple times if it divides the value - * multiple times. + * By default, a factor will be printed numtiple times if it divides + * the value multiple times. + * + * If hflag is specified, duplicate factors are printed in "human- + * readable" form of x^n. * * Factors are printed with leading tabs. */ static void -pr_fact(BIGNUM *val) +pr_fact(BIGNUM *val, int hflag) { const uint64_t *fact; /* The factor found. */ + int i; /* Firewall - catch 0 and 1. */ if (BN_is_zero(val) || BN_is_one(val)) @@ -236,11 +247,20 @@ pr_fact(BIGNUM *val) } /* Divide factor out until none are left. */ + i = 0; do { - printf(" %" PRIu64, *fact); + i++; + if (!hflag) + printf(" %" PRIu64, *fact); BN_div_word(val, (BN_ULONG)*fact); } while (BN_mod_word(val, (BN_ULONG)*fact) == 0); + if (hflag) { + printf(" %" PRIu64, *fact); + if (i > 1) + printf("^%d", i); + } + /* Let the user know we're doing something. */ fflush(stdout); } @@ -265,7 +285,7 @@ BN_print_dec_fp(FILE *fp, const BIGNUM *num) void usage(void) { - fprintf(stderr, "usage: factor [value ...]\n"); + fprintf(stderr, "usage: factor [-h] [value ...]\n"); exit (0); } -- cgit v1.2.3-56-ge451