F = 
why does factor(1) return 1? shouldn't it return null?
Ältere Kommentare anzeigen
I'm using factor() to find the prime factors of a range of numbers.
As far as I understand it (which may be very limited as I am new to this!), factor(n) should accept a value of n=1 as 1 is a "real, nonnegative integer scalar", but should only return prime factors.
I believe that 1 is not regarded as a prime.
Given this, shouldn't the function return an empty/null row vector?
Thanks.
2 Kommentare
Andrew
vor 15 Minuten
John D'Errico
vor etwa 8 Stunden
A virtue of MATLAB is it is easily extensible, even trivially so. If the behavior of a function on a boundary case like this is a problem, then just write your own code, call it primeFactors. It could be as simple as this:
function Xfac = primeFactors(X)
% primeFactors - generate the list of all prime factors of X
if x >= 2
Xfac = factor(X);
else
Xfac = [];
end
end
And of course, primeFactors has your desired behavior, and is pedantically correct, in that 1 or 0 have no prime factorization under the fundamental theorem of arithmetic.
But as you recognize, changing the code would seem to make little sense. Even putting a switch in there, to return empty when the users desires that behavior for the edge cases seems needlessly complex. A comment in the help indicating the behavior on edge cases? Yes, of couse. That never hurts to remove any confusion.
Anyway, this is a good catch on your part, that the help needs to be updated to be made clear.
Akzeptierte Antwort
Weitere Antworten (2)
Technically, yes. If you want prod(factor(x)) to return x and the output of factor to only include prime numbers, having factor(1) return the empty matrix would be consistent.
But there would still be an inconsistency -- what should factor(0) return? 0 isn't prime. Having it error feels like it could be technically correct but practically annoying. [The fundamental theorem of arithmetic covers integer values greater than 1, so technically it doesn't apply to either of those cases.]
Doing a little archaeology and going back to the earliest version of factor.m that I have access to (over 30 years old) I believe factor(1) would actually error (with an incorrect error message.)
Almost 27 years ago, factor.m was modified to just return the input if that input is non-negative and is less than 4. That code is still present in factor.m today. This optimization works for n = 3 and n = 2. It's this that causes factor to return 1 for n = 1 and 0 for n = 0. [Negative values are checked for and cause factor to error out on an earlier line of code.]
dbtype 29:34 factor.m
We could change how factor.m behaves in the n = 1 case (and in the n = 0 case as well.) But given how long this behavior has been in the product I'd be hesitant to change it without a good use case and an analysis of the potential impact of the incompatibility.
2 Kommentare
John D'Errico
vor 18 Minuten
@Steven Lord - I agree, that factor as applied to 0 or 1 should remain as they are. But I do think the help should reflect that.
Steven Lord
vor etwa eine Stunde
That's fair. They are edge cases and as such it's reasonable to ask that they be documented.
John D'Errico
am 1 Jul. 2026 um 17:22
Bearbeitet: John D'Errico
am 1 Jul. 2026 um 17:44
Yes, I agree, in that
f1 = factor(1)
could arguably return empty. 1 is not indeed prime, and so the result is inconsistent with the documentation.
I'd also note that
f0 = factor(0)
fails to return a set of prime factors. Again, 0 is not prime.
However, you could also argue that 1 is indeed a "factor" of the number 1. In fact, it is the only such number that divides 1, and is not itself reducible. It is just that 1 is technically not a prime factor of 1, which lacks any truly prime factors at all. It gets even more difficult to decide what should be returned for the factor(s) of 0. But the help for factor allows any non-negative arguement.
It is also true that the product of the vector returned by factor reproduces the input. And so we see that
prod(f0)
prod(f1)
do indeed reproduce the original number as factored. And this could be a useful property of factor, relied upon in legacy code, going back as much as 40 years now. Yes, factor has been doing this for a long time. And any change to factor would potentially cause legacy code to fail were they to arbitrarily change the code. That would mean any change to factor would need to happen with a long lead time. They would probably keep reminding us for multiple years to change any code that relies on factor(1).
Personally, I think the argument about what should be returned as the factors of either 0 or 1 as being more a pedantic thing, up there with the number of angels that fit on the head of a pin. I don't think it merits a need to change the code, because of the issues that might potentially cause.
Better I think is to just introduce a documentation change, indicating that factor(1) will return 1 as a special case (the same applies to factor(0)). That can happen quite quickly, probably seeing such a change reflected in R2027, or even sooner. A change to the documentation IS DEFINITELY a good idea here. I would recommend this be introduced to support. I'll post it as a request today.
4 Kommentare
dpb
vor etwa eine Stunde
I don't suppose the archeology uncovered any other rationale notes besides the shortcut, but I presumed that keeping the product of the results of factor() reproducing the inputs was the motivation. I agree also on only a documentation update as noted before. I hadn't ever thought of it specifically before as I don't know that had ever had reason to inspect factor(1) before...
John D'Errico
vor 3 Minuten
Funny thing is, I don't think it ever bothered me either. Returning a factorization that contains 1 (or 0) just seems to make more sense. Do I really want factor to generate an error message for a boundary case like this? Not really. And even returning an empty vector for factor(1) or factor(0), that now would fail the requirement that prod(factor(n))==N. So I sort of like the return of a non-prime for those boundary cases.
And that means, in my eyes, really the only right thing to do is to update the documentation. Just have it say that well, yeah, factor does not return primes for these special cases, but what can we do there?
Thanks to everyone for their input on this matter. I agree that the documentation should be updated for the exceptions: 1, 0, -1. Prime factorization also extends to negative integers. However, it extracts the negative sign as an irreducible unit (-1), rather than treating it as a prime.
F = factor(sym(-6))
It is also intriguing to investigate the computational limits of the factor command. I test the special class of numbers called Mersenne primes, which take the form
, where p is also a prime.
F = factor(sym(2^53 - 1))
It correctly returns 3 distinct prime factors.
I also test this case further. Consider the value 2^53 + 2. This is not a Mersenne prime, but it is known to produce 4 distinct prime factors: 2 × 17 × 858001 × 308761441. Yet, the factor command returns this result:
F = factor(sym(2^53 + 2))

The issue is likely related to flintmax, which equals 2^53, the largest consecutive integer in IEEE double precision. However, I feel it should not produce a run of 2s. Therefore, the documentation should specifically state that for every nonnegative integer x with
, factor returns the prime factorization of x.
, factor returns the prime factorization of x. flintmax
For numbers that large, don't operate using double. Use a 64 bit integer instead, but be careful how you compute it in the first place.
two = uint64(2);
x = two^53+two;
factor(x)
Or if you want to do this symbolically:
two = sym(2);
x = two^53+two;
factor(x)
Kategorien
Mehr zu Characters and Strings finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!