Add the two options netbsd has for this command.

This commit is contained in:
Rob Landley 2022-05-04 19:34:58 -05:00
parent c3c3670b9d
commit 529fe97a4b
2 changed files with 23 additions and 20 deletions

View File

@ -20,3 +20,8 @@ testing "10000000019" "factor 10000000019" \
testing "3 6 from stdin" "factor" "3: 3\n6: 2 3\n" "" "3 6"
testing "stdin newline" "factor" "3: 3\n6: 2 3\n" "" "3\n6\n"
testing "-h" "factor -h $(((1<<63)-26))" \
"9223372036854775782: 2 3^4 17 23 319279 456065899\n" "" ""
testing "-x" "factor -x $(((1<<63)-20))" \
"7fffffffffffffec: 2 2 3 283 43f2ba978e663\n" "" ""

View File

@ -3,8 +3,10 @@
* Copyright 2014 Rob Landley <rob@landley.net>
*
* See https://man7.org/linux/man-pages/man1/factor.1.html
*
* -h and -x options come from https://man.netbsd.org/factor.6
USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN))
USE_FACTOR(NEWTOY(factor, "?hx", TOYFLAG_USR|TOYFLAG_BIN))
config FACTOR
bool "factor"
@ -13,17 +15,22 @@ config FACTOR
usage: factor NUMBER...
Factor integers.
-h Human readable: show repeated factors as x^n
-x Hexadecimal output
*/
#define FOR_factor
#include "toys.h"
static void factor(char *s)
{
unsigned long long l, ll, lll;
char *pat1 = FLAG(x) ? " %llx" : " %llu", *pat2 = FLAG(x) ? "^%x" : "^%u";
for (;;) {
char *err = s;
int dash = 0;
int dash = 0, ii;
while(isspace(*s)) s++;
if (*s=='-') dash = *s++;
@ -37,34 +44,25 @@ static void factor(char *s)
continue;
}
printf("-%llu:"+!dash, l);
if (dash) xputc('-');
printf(pat1+1, l);
xputc(':');
// Negative numbers have -1 as a factor
if (dash) printf(" -1");
// Nothing below 4 has factors
if (l < 4) {
printf(" %llu\n", l);
continue;
}
// Special case factors of 2
while (l && !(l&1)) {
printf(" 2");
l >>= 1;
}
// test odd numbers until square is > remainder or integer wrap.
for (ll = 3;; ll += 2) {
// test 2 and odd numbers until square is > remainder or integer wrap.
for (ll = 2;; ll += 1+(ll!=2)) {
lll = ll*ll;
if (lll>l || lll<ll) {
if (l>1) printf(" %llu", l);
if (l>1 || ll==2) printf(pat1, l);
break;
}
while (!(l%ll)) {
printf(" %llu", ll);
for (ii = 0; !(l%ll); ii++) {
if (!ii || !FLAG(h)) printf(pat1, ll);
l /= ll;
}
if (ii>1 && FLAG(h)) printf(pat2, ii);
}
xputc('\n');
}