I recently found out that GNU coreutils 'factor' misbehaves if its
internal word is 128 bits rather than the usual 64. This could happen if
one builds Coreutils 9.7 on a platform with 128-bit uintmax_t, something
that POSIX allows (though it's only theoretical now as far as I know).
The problem occurs when src/factor.c's prime_p function assumes that as
a quick test, its argument N must be prime if N is less than
FIRST_OMITTED_PRIME * FIRST_OMITTED_PRIME. I guess this quick-test
assumption is true for 64-bit uintmax_t, but not for 128-bit.
I worked around the bug by installed a patch
<https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=fe51b33859d2e7286425d6d5600288ce9ae43bd1>.
This patch changes prime_p to rely on the quick-test assumption only
when the internal word size is 64 bits. On platforms with wider words,
the code now tests smaller numbers for primes too; this works around the
bug, but is slower.
It'd be nice if the underlying problem were fixed, so that the code is
more portable to 128-bit word.
The issue might be related to Bug#25135 "Infinite loop in factor"
<https://bugs.gnu.org/25135> so I am cc'ing this to Torbjörn. The
current factor.c is not the same as what Torbjörn contributed years ago
so it is of course possible that I or someone else introduced the bug
more recently.
To reproduce the problem on Fedora 42 x86-64:
git clone https://git.savannah.gnu.org/git/coreutils.git
cd coreutils
git checkout fe51b33859d2e7286425d6d5600288ce9ae43bd1
./bootstrap
./configure
make CFLAGS='-DUSE_INT128 -DEXHIBIT_INT128_BUG' WERROR_CFLAGS=
echo 340282366920938463463374607431768211355 | src/factor
The output is:
340282366920938463463374607431768211355: 155
2195370109167344925570158757624311041
which is wrong, as 155 is not prime.