将以下文本翻译成中文:
在C语言中,要对整数进行因式分解,可以尝试使用一种概率方法:
我的建议标题:
#include <stdlib.h>
#include <sys/time.h>
typedef unsigned long long int positive_number;
static inline positive_number multiplication_modulo(positive_number lhs, positive_number rhs, positive_number mod);
static int is_prime(positive_number n, int k);
positive_number factor_worker(positive_number n);
positive_number factor(positive_number n, int timeout);
因为有超时,分解过程被管理器管理:
double microtime() {
struct timeval time; gettimeofday(&time, 0);
return (double) time.tv_sec + (double) time.tv_usec / 1e6;
}
positive_number factor(positive_number n, int timeout) {
if (n < 4) return n;
if (n != (n | 1)) return 2;
double begin = microtime();
int steps = 8;
positive_number a, b;
for (a = n >> 1, b = (a + n / a) >> 1; b < a; a = b, b = (a + n / a) >> 1, ++steps);
if (b * b == n) return b ;
if (is_prime(n, steps)) return n;
do { positive_number res = factor_worker(n);
if (res != n) return res;
if (++steps % 96 == 0 && is_prime(n, 32)) return n ;
} while (microtime() - begin < timeout);
return n;
}
"乘法器" 助手因为计算是模 N 进行的:
static inline positive_number multiplication_modulo(positive_number lhs, positive_number rhs, positive_number mod) {
positive_number res = 0;
for (lhs %= mod, rhs%= mod; rhs; (rhs & 1) ? (res = (res + lhs) % mod) : 0, lhs = (lhs << 1) % mod, rhs >>= 1);
return res;
}
这是英语文本,已经是中文了。它的意思是:“当然,这是“质数检查器”助手:”。
static int is_prime(positive_number n, int k) {
positive_number a = 0, b, c, d, e, f, g; int h, i;
if ((n == 1) == (n & 1)) return n == 2;
if (n < 51529)
return (n & 1) & ((n < 6) * 42 + 0x208A2882) >> n % 30 && (n < 49 || (n % 7 && n % 11 && n % 13 && n % 17 && n % 19 && n % 23 && n % 29 && n % 31 && n % 37 && (n < 1369 || (n % 41 && n % 43 && n % 47 && n % 53 && n % 59 && n % 61 && n % 67 && n % 71 && n % 73 && ( n < 6241 || (n % 79 && n % 83 && n % 89 && n % 97 && n % 101 && n % 103 && n % 107 && n % 109 && n % 113 && ( n < 16129 || (n % 127 && n % 131 && n % 137 && n % 139 && n % 149 && n % 151 && n % 157 && n % 163 && n % 167 && ( n < 29929 || (n % 173 && n % 179 && n % 181 && n % 191 && n % 193 && n % 197 && n % 199 && n % 211 && n % 223))))))))));
for (b = c = n - 1, h = 0; !(b & 1); b >>= 1, ++h);
for (; k--;) {
for (g = 0; g < sizeof(positive_number); ((char*)&a)[g++] = rand());
do for (d = e = 1 + a % c, f = n; (d %= f) && (f %= d););
while (d > 1 && f > 1);
for (d = f = 1; f <= b; f <<= 1);
for (; f >>= 1; d = multiplication_modulo(d, d, n), f & b && (d = multiplication_modulo(e, d, n)));
if (d == 1) continue;
for (i = h; i-- && d != c; d = multiplication_modulo(d, d, n));
if (d != c) return 0;
}
return 1;
}
因式分解“worker”,一次调用不能保证成功,它是一个概率性的尝试。
positive_number factor_worker(positive_number n) {
size_t a; positive_number b = 0, c, d, e, f;
for (a = 0; a < sizeof(positive_number); ((char*)&b)[a++] = rand());
c = b %= n;
do {
b = multiplication_modulo(b, b, n); if(++b == n) b = 0;
c = multiplication_modulo(c, c, n); if(++c == n) c = 0;
c = multiplication_modulo(c, c, n); if(++c == n) c = 0;
for (d = n, e = b > c ? b - c : c - b; e; f = e, e = multiplication_modulo(d / f, f, n), e = (d - e) % n, d = f);
} while (d == 1);
return d;
}
使用示例:
#include <stdio.h>
positive_number exec(positive_number n) {
positive_number res = factor(n, 2);
if (res == n) return res + printf("%llu * ", n) * fflush(stdout) ;
return exec(res) * exec(n / res);
}
int main() {
positive_number n = 0, mask = -1, res;
for (int i = 0; i < 1000;) {
int bits = 4 + rand() % 60;
for (size_t k = 0; k < sizeof(positive_number); ((char*)&n)[k++] = rand());
n &= mask >> (8 * sizeof (positive_number) - bits); n += 4;
printf("%5d. (%2d bits) %llu = ", ++i, bits, n);
res = exec(n);
if (res != n) return 1;
printf("1\n");
}
}
你可以把它放进一个名为
primes.c
的文件中,然后编译并执行:
gcc -O3 -std=c99 -Wall -pedantic primes.c ; ./a.out ;
此外,
128位整数GCC扩展 扩展可能可用。
示例输出:
358205873110913227 = 380003149 * 942639223 took 0.01s
195482582293315223 = 242470939 * 806210357 took 0.0021s
107179818338278057 = 139812461 * 766597037 took 0.0023s
44636597321924407 = 182540669 * 244529603 took 0s
747503348409771887 = 865588487 * 863578201 took 0.016s
170141183460469231731687303715506697937 =
13602473 * 230287853 * 54315095311400476747373 took 0.646652s
信息:这个C99 100行概率分解软件建议基于米勒-拉宾素性测试,然后是波拉德的rho算法。和你一样,我最初的目标只是分解一些小的long long int。根据我的测试,它对我来说运行得足够快,即使是一些更大的数。谢谢。
该软件“按原样”提供,不提供任何形式的保证。