These factors are the positive integers by which the number being factored can be divided to yield a positive integer result.

(Though the concepts function correctly for zero and negative integers, the set of factors of zero has countably infinite members, and the factors of negative integers can be obtained from the factors of related positive numbers without difficulty; this task does not require handling of either of these cases).

/* Calculate the factors of n and return their count. * This function mutates the global array f[] which will * contain all factors of n in ascending order after the call! */define f(n) { auto i, d, h, h[], l, o /* Local variables: * i: Loop variable. * d: Complementary (higher) factor to i. * h: Will always point to the last element of h[]. * h[]: Array to hold the greater factor of the pair (x, y), where * x * y == n. The factors are stored in descending order. * l: Will always point to the next free spot in f[]. * o: For saving the value of scale. */

Improved version. Considers small factors from 1 up to (sqrt n) -- we increment it because range does not include the end point. Pair each small factor with its co-factor, flattening the results, and put them into a sorted set to get the factors in order.

# Reference implementation for finding factors is slow, but hopefully# robust--we'll use it to verify the more complicated (but hopefully faster)# algorithm.slow_factors = (n)->(i for i in[1..n]when n % i == 0)

# The rest of this code does two optimizations:# 1) When you find a prime factor, divide it out of n (smallest_prime_factor).# 2) Find the prime factorization first, then compute composite factors from those.

Frink has built-in factoring functions which use wheel factoring, trial division, Pollard p-1 factoring, and Pollard rho factoring. It also recognizes some special forms (e.g. Mersenne numbers) and handles them efficiently. Integers can either be decomposed into prime factors or all factors.

The factors[n] function will return the prime decomposition of n.

The allFactors[n, include1=true, includeN=true, sort=true, onlyToSqrt=false] function will return all factors of n. The optional arguments include1 and includeN indicate if the numbers 1 and n are to be included in the results. If the optional argument sort is true, the results will be sorted. If the optional argument onlyToSqrt=true, then only the factors less than or equal to the square root of the number will be produced.

The set of factors of 103 is {1, 103}
The set of factors of 316 is {158, 4, 79, 1, 2, 316}
The set of factors of 519 is {1, 3, 173, 519}
The set of factors of 639 is {9, 639, 71, 213, 1, 3}
The set of factors of 760 is {8, 19, 4, 40, 152, 5, 10, 76, 1, 95, 190, 760, 20, 2, 38, 380}

The above function can also be found in the package arithmoi, as Math.NumberTheory.Primes.factorise :: Integer -> [(Integer, Int)], which performs "factorisation of Integers by the elliptic curve algorithm after Montgomery" and "is best suited for numbers of up to 50-60 digits".

From here, it's a simple matter (*/&>@{) to compute all possible factors of the original number

factrs=: */&>@{@((^ i.@>:)&.>/)@q:~&__ factrs 4015210420840

However, a data structure which is organized around the prime decomposition of the argument can be hard to read. So, for reader convenience, we should probably arrange them in a monotonically increasing list:

This following function is elegant looking and concise. However, it will not handle large numbers well: it will consume a great deal of memory (on one large number, the function consumed 4.3GB of memory on my desktop machine):

Start finding all factors of 10677106534462215678539721403561279:10677106534462215678539721403561279=29269^1*32579^1*98731^2*104729^31122926933257949873151047296953554751728897576398306531310193216557249103411966091119747810361121033999889913109681634411494145414120981159986483551747916285308661456109173026414277748311831757391375101919321027175754629203368668241305212135733179674433922102087843129716923108289774469337124114868478901248925929507088157857511126985975507547621914927104587443589100581912829880090805636839461293169533408943027579930332591984132304688513133620855089606540541323527972562436533380933374230017412378791313410691557723132121220135113410797903992051459369734634783568425927999193710326022892995489552556213810953338379642914842852393931293120299835405599110694033194206438519433541534714134832025906192137722963794236948103849141570444827614311197161487859039232598529441019498566248337679013427169514510814340515605246253496593170946327729719588146219298926345301473647923241129596391588274762914810677106534462215678539721403561279done

Mercury is both a logic language and a functional language. As such there are two possible interfaces for calculating the factors of an integer. This code shows both styles of implementation. Note that much of the code here is ceremony put in place to have this be something which can actually compile. The actual factoring is contained in the predicate factor/2 and in the function factor/1. The function form is implemented in terms of the predicate form rather than duplicating all of the predicate code.

The predicates main/2 and factor/2 are shown with the combined type and mode statement (e.g. int::in) as is the usual case for simple predicates with only one mode. This makes the code more immediately understandable. The predicate factor/5, however, has its mode broken out onto a separate line both to show Mercury's mode statement (useful for predicates which can have varying instantiation of parameters) and to stop the code from extending too far to the right. Finally the function factor/1 has its mode statements removed (shown underneath in a comment for illustration purposes) because good coding style (and the default of the compiler!) has all parameters "in"-moded and the return value "out"-moded.

This implementation of factoring works as follows:

The input number itself and 1 are both considered factors.

The numbers between 2 and the square root of the input number are checked for even division.

If the incremental number divides evenly into the input number, both the incremental number and the quotient are added to the list of factors.

This implementation makes use of Mercury's "state variable notation" to keep a pair of variables for accumulation, thus allowing the implementation to be tail recursive. !Accumulator is syntax sugar for a *pair* of variables. One of them is an "in"-moded variable and the other is an "out"-moded variable. !:Accumulator is the "out" portion and !.Accumulator is the "in" portion in the ensuing code.

Using the state variable notation avoids having to keep track of strings of variables unified in the code named things like Acc0, Acc1, Acc2, Acc3, etc.

factors(num) New fctr,list,sep,sqrt If num<1 Quit "Too small a number" If num["." Quit "Not an integer" Set sqrt=num**0.5\1 For fctr=1:1:sqrt Set:num/fctr'["." list(fctr)=1,list(num/fctr)=1 Set (list,fctr)="",sep="[" For Set fctr=$Order(list(fctr)) Quit:fctr="" Set list=list_sep_fctr,sep="," Quit list_"]"

sub factors {my$n=shift;$n=-$nif$n<0;my@divisors;for(1..int(sqrt($n))){# faster and less memory than map/greppush@divisors,$_unless$n%$_;}# Return divisors including top half, without duplicating a square@divisors,map{$_*$_==$n?():int($n/$_)}reverse@divisors;}printjoin" ", factors(64),"\n";

Here the range of integers is only taken up to the square root of the number, the same filtering applies. Afterwards the corresponding larger factors are calculated and sent down the pipeline along with the small ones found earlier.

This REXX version has no effective limits on the number of decimal digits in the number to be factored [by adjusting the number of digits (precision)].
This REXX version also supports negative integers and zero.

It also indicates primes in the output listing as well as the number of factors.
It also displays a final count of the number of primes found.

/* REXX **************************************************************** Program to calculate and show divisors of positive integer(s).* 03.08.2012 Walter Pachl simplified the above somewhat* in particular I see no benefit from divAdd procedure* 04.08.2012 the reference to 'above' is no longer valid since that* was meanwhile changed for the better.* 04.08.2012 took over some improvements from new above**********************************************************************/Parsearg low high .SelectWhen low=''ThenParseValue'1 200'with low highWhen high=''Then high=lowOtherwiseNopEnddo j=low to highsay' n = 'right(j,6)" divisors = " divs(j)endexit

Another idea would be to approximate an upper bound for the square root of "n" with some bit twiddling such as &!*K31 "n", which evaluates to a binary number of all 1's half the width of "n" rounded up, and another would be to use the division function to get the quotient and remainder at the same time. Combining these ideas, losing the dummy variable, and cleaning up some other cruft, we have