Skip to content

Commit b63412e

Browse files
committed
Hashtable: Extend nextPrime() to support 64-bit size range
Extend the nextPrime() function so that it can report primes up to (2^63 - 25). The old prime number sequence stops at (2^37 - 25). Although it's possible to extend the sequence https://oeis.org/A014234 to support up to 2^63, the code size can be smaller by encoding the differences to the prime numbers (i.e. the sequence https://oeis.org/A013603 ) as the array instead. The next prime in the sequence, (2^64 - 59), is not useful for the Hashtable purpose (and it exceeds SSIZE_MAX) and so is left out. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
1 parent ab3192e commit b63412e

1 file changed

Lines changed: 15 additions & 14 deletions

File tree

Hashtable.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ in the source distribution for its full text.
1010
#include "Hashtable.h"
1111

1212
#include <assert.h>
13+
#include <limits.h>
1314
#include <stdint.h>
1415
#include <stdlib.h>
1516
#include <string.h>
@@ -88,21 +89,21 @@ size_t Hashtable_count(const Hashtable* this) {
8889

8990
#endif /* NDEBUG */
9091

91-
/* https://oeis.org/A014234 */
92-
static const uint64_t OEISprimes[] = {
93-
7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191,
94-
16381, 32749, 65521, 131071, 262139, 524287, 1048573,
95-
2097143, 4194301, 8388593, 16777213, 33554393,
96-
67108859, 134217689, 268435399, 536870909, 1073741789,
97-
2147483647, 4294967291, 8589934583, 17179869143,
98-
34359738337, 68719476731, 137438953447
99-
};
100-
10192
static size_t nextPrime(size_t n) {
102-
/* on 32-bit make sure we do not return primes not fitting in size_t */
103-
for (size_t i = 0; i < ARRAYSIZE(OEISprimes) && OEISprimes[i] < SIZE_MAX; i++) {
104-
if (n <= OEISprimes[i])
105-
return OEISprimes[i];
93+
// Table of differences so that (2^m - primeDiffs[m]) is a prime.
94+
// This is OEIS sequence https://oeis.org/A013603 except for
95+
// entry 0 (2^0 = 1 as a non-prime special case).
96+
static const uint8_t primeDiffs[64] = {
97+
0, 0, 1, 1, 3, 1, 3, 1, 5, 3, 3, 9, 3, 1, 3, 19,
98+
15, 1, 5, 1, 3, 9, 3, 15, 3, 39, 5, 39, 57, 3, 35, 1,
99+
5, 9, 41, 31, 5, 25, 45, 7, 87, 21, 11, 57, 17, 55, 21, 115,
100+
59, 81, 27, 129, 47, 111, 33, 55, 5, 13, 27, 55, 93, 1, 57, 25,
101+
};
102+
103+
for (uint8_t shift = 3; shift < sizeof(n) * CHAR_BIT && shift < ARRAYSIZE(primeDiffs); shift++) {
104+
size_t prime = ((size_t)1 << shift) - primeDiffs[shift];
105+
if (n <= prime)
106+
return prime;
106107
}
107108

108109
CRT_fatalError("Hashtable: no prime found");

0 commit comments

Comments
 (0)