Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

164 lines
4.2 KiB
C

static char sccsid[] = "@(#)46 1.11 src/bos/usr/bin/factor/factor.c, cmdmisc, bos41B, 9504A 1/4/95 14:11:47";
/*
* COMPONENT_NAME: (CMDMISC) miscellaneous commands
*
* FUNCTIONS:
*
* ORIGINS: 3, 26, 27
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1985, 1994
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*
*/
/*
* NOTES:
* To COMPILE: cc -O factor.c -s -i -lm -o factor
* works up to 14 digit numbers
* runumbering time is proportional to sqrt(n)
* accepts arguments either as input or on command line
* 0 input terminates processing
*/
double modf(), sqrt();
static double number, bigfact;
/* This is the largest number which can be factored. */
static double huge = 1.0e14;
/* This array is used to compute the prime numbers. */
static double sq[] = {
10, 2, 4, 2, 4, 6, 2, 6,
4, 2, 4, 6, 6, 2, 6, 4,
2, 6, 4, 6, 8, 4, 2, 4,
2, 4, 8, 6, 4, 6, 2, 4,
6, 2, 6, 6, 4, 2, 4, 6,
2, 6, 4, 2, 4, 2,10, 2,
};
#include <stdlib.h>
#include <locale.h>
#include "factor_msg.h"
#define MSGSTR(Num, Str) catgets(catd, MS_FACTOR, Num, Str)
static nl_catd catd;
main(argc, argv)
int argc;
char *argv[];
{
int test = 1;
int ret;
register j;
double junk;
double fr;
double facter;
char *cp;
(void) setlocale (LC_ALL, "");
catd = catopen(MF_FACTOR, NL_CAT_LOCALE);
/* There can be no more than two arguments. */
if(argc > 2){
fprintf(stderr,MSGSTR(USAGE, "Usage: factor [number]\n"));
exit(1);
}
while(test == 1){
/* If a number is given as an argument, then find its
* factors, otherwise read the numbers from stdin. */
if(argc == 2){
/* First arg read as flt-pt and placed in number. */
cp = argv[1];
number = strtod(cp, &cp);
fr = modf(number, &junk);
if (fr>0 || *cp!='\0' || number<=0.0 || number>huge) {
fprintf(stderr,MSGSTR(NOTINT,"factor: specify an integer ranging from 1 to 1.0e14.\n"));
fprintf(stderr,MSGSTR(USAGE, "Usage: factor [number]\n"));
exit(1);
}
test = 0;
printf("%.0f\n", number);
} else {
ret = scanf("%lf", &number);
if ((ret<1) || (number == 0.0)) {
exit(0);
}
fr = modf(number, &junk);
/* check if the number is an integer or inside the
* the range from 1 to 1.0e14, if not, print out
* error message.
*/
if((fr != 0.0) || (number < 0.0) || (number > huge)) {
fprintf(stderr,MSGSTR(NOTINT,
"factor: specify an integer ranging from 1 to 1.0e14.\n"));
continue;
}
}
/* Use the number 2,3,5 and 7 as factors first. */
try(2.0);
try(3.0);
try(5.0);
try(7.0);
/* The factor cannot be greater than this number(bigfact). */
bigfact = 1 + sqrt(number);
/* facter holds the numbers which are being tried as factors */
facter = 1.0;
/* Process the loop until we're trying factors which are
* impossibly large. */
while(facter <= bigfact){
/* This loop computes all the prime numbers and uses
* them as factors into the number. */
for(j=0; j<48; j++){
facter += sq[j];
try(facter);
}
}
/* If the number as been factored as much as possible, then
* print the final factor. */
if(number > 1.0){
printf(" %.0f\n", number);
}
printf("\n");
}
exit(0);
}
/*
* NAME: try
*
* FUNCTION: This function is passed a number and it determines
* if that number is a factor. If it is, then it's
* divided out, printed and tried again. This function
* stops after it's determined that the number is no
* longer a factor.
*
* RETURN VALUE: none
*
*/
static try(arg)
double arg;
{
double temp;
int divisor = 1;
while (divisor == 1) {
modf(number/arg, &temp);
if(number == temp*arg) {
printf(" %.0f\n", arg);
number = number/arg;
bigfact = 1 + sqrt(number);
}
else divisor = 0;
}
return;
}