-
Notifications
You must be signed in to change notification settings - Fork 2
/
bigs.h
124 lines (105 loc) · 3.12 KB
/
bigs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
*
* Copyright (c) 2010-2015 Voidware Ltd. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code as
* defined in and that are subject to the Voidware Public Source Licence version
* 1.0 (the 'Licence'). You may not use this file except in compliance with the
* Licence or with expressly written permission from Voidware. Please obtain a
* copy of the Licence at http://www.voidware.com/legal/vpsl1.txt and read it
* before using this file.
*
* The Original Code and all software distributed under the Licence are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
* OR IMPLIED, AND VOIDWARE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING
* WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Please see the Licence for the specific language governing rights and
* limitations under the Licence.
*
*/
#ifndef __bigs_h__
#define __bigs_h__
#include "big.h"
#include "bcdmath.h"
#define DEFAULT_PRIMETEST_LIMIT 50
struct SmallDivs
{
// generator of small trial divisors
// return small divisors > 7, not multiples of 2, 3, 5
SmallDivs() { _ai = 0; _d = 7; }
unsigned int next()
{
static unsigned char add[] = {4, 2, 4, 2, 4, 6, 2, 6};
_d += add[_ai++];
_ai &= 0x7;
return _d;
}
unsigned int _ai;
unsigned int _d;
};
struct CompState
{
// state of `isComposite' so we can continue testing.
CompState(const BigInt& n) : _n(n)
{
_r = 0;
_nm1 = (_n - 1).give();
_s = _nm1;
_dn = 0;
_limit = 0;
// factor out 2's
while (_s.isEven())
{
_s >>= 1;
++_r;
}
}
#if 0
void setReimannLimit()
{
// min witness = min(floor(2ln(n)^2), n-1)
if (_n < 30)
_limit = _nm1.asUInt();
else
{
BCD v = log(_n.asBCD());
_limit = ifloor(v*v*2);
}
}
#endif
void setDefaultLimit()
{
_limit = _nm1.asUInt();
// NB: if too big, limit = -1U and this test passes
if (_limit > DEFAULT_PRIMETEST_LIMIT)
_limit = DEFAULT_PRIMETEST_LIMIT;
}
bool done() const { return _dn > _limit; }
void next()
{
static unsigned char primes[] =
{ 2, 0, 3, 5, 0, 7 };
if (_dn < 7)
_dn = primes[_dn];
else
_dn = _divs.next();
}
const BigInt& _n;
unsigned int _limit;
BigInt _nm1; // n-1
BigInt _s; // n without 2's
unsigned int _r;
unsigned int _dn;
SmallDivs _divs;
};
int isPrime(const BigInt&);
bool Lenstra(const BigInt& n, BigInt& f, int ntrials);
bool isOddComposite(CompState& st);
bool nextPrime(const BigInt& n0, BigInt& np);
bool prevPrime(const BigInt& n0, BigInt& np);
bool isOddCompositeAux(CompState& st);
BigInt nRoot(const BigInt& n, unsigned int k);
#endif // __bigs_h__