primes.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. // Copyright (c) 2014 The mathutil Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package mathutil
  5. import (
  6. "math"
  7. )
  8. // IsPrimeUint16 returns true if n is prime. Typical run time is few ns.
  9. func IsPrimeUint16(n uint16) bool {
  10. return n > 0 && primes16[n-1] == 1
  11. }
  12. // NextPrimeUint16 returns first prime > n and true if successful or an
  13. // undefined value and false if there is no next prime in the uint16 limits.
  14. // Typical run time is few ns.
  15. func NextPrimeUint16(n uint16) (p uint16, ok bool) {
  16. return n + uint16(primes16[n]), n < 65521
  17. }
  18. // IsPrime returns true if n is prime. Typical run time is about 100 ns.
  19. //
  20. //TODO rename to IsPrimeUint32
  21. func IsPrime(n uint32) bool {
  22. switch {
  23. case n&1 == 0:
  24. return n == 2
  25. case n%3 == 0:
  26. return n == 3
  27. case n%5 == 0:
  28. return n == 5
  29. case n%7 == 0:
  30. return n == 7
  31. case n%11 == 0:
  32. return n == 11
  33. case n%13 == 0:
  34. return n == 13
  35. case n%17 == 0:
  36. return n == 17
  37. case n%19 == 0:
  38. return n == 19
  39. case n%23 == 0:
  40. return n == 23
  41. case n%29 == 0:
  42. return n == 29
  43. case n%31 == 0:
  44. return n == 31
  45. case n%37 == 0:
  46. return n == 37
  47. case n%41 == 0:
  48. return n == 41
  49. case n%43 == 0:
  50. return n == 43
  51. case n%47 == 0:
  52. return n == 47
  53. case n%53 == 0:
  54. return n == 53 // Benchmarked optimum
  55. case n < 65536:
  56. // use table data
  57. return IsPrimeUint16(uint16(n))
  58. default:
  59. mod := ModPowUint32(2, (n+1)/2, n)
  60. if mod != 2 && mod != n-2 {
  61. return false
  62. }
  63. blk := &lohi[n>>24]
  64. lo, hi := blk.lo, blk.hi
  65. for lo <= hi {
  66. index := (lo + hi) >> 1
  67. liar := liars[index]
  68. switch {
  69. case n > liar:
  70. lo = index + 1
  71. case n < liar:
  72. hi = index - 1
  73. default:
  74. return false
  75. }
  76. }
  77. return true
  78. }
  79. }
  80. // IsPrimeUint64 returns true if n is prime. Typical run time is few tens of µs.
  81. //
  82. // SPRP bases: http://miller-rabin.appspot.com
  83. func IsPrimeUint64(n uint64) bool {
  84. switch {
  85. case n%2 == 0:
  86. return n == 2
  87. case n%3 == 0:
  88. return n == 3
  89. case n%5 == 0:
  90. return n == 5
  91. case n%7 == 0:
  92. return n == 7
  93. case n%11 == 0:
  94. return n == 11
  95. case n%13 == 0:
  96. return n == 13
  97. case n%17 == 0:
  98. return n == 17
  99. case n%19 == 0:
  100. return n == 19
  101. case n%23 == 0:
  102. return n == 23
  103. case n%29 == 0:
  104. return n == 29
  105. case n%31 == 0:
  106. return n == 31
  107. case n%37 == 0:
  108. return n == 37
  109. case n%41 == 0:
  110. return n == 41
  111. case n%43 == 0:
  112. return n == 43
  113. case n%47 == 0:
  114. return n == 47
  115. case n%53 == 0:
  116. return n == 53
  117. case n%59 == 0:
  118. return n == 59
  119. case n%61 == 0:
  120. return n == 61
  121. case n%67 == 0:
  122. return n == 67
  123. case n%71 == 0:
  124. return n == 71
  125. case n%73 == 0:
  126. return n == 73
  127. case n%79 == 0:
  128. return n == 79
  129. case n%83 == 0:
  130. return n == 83
  131. case n%89 == 0:
  132. return n == 89 // Benchmarked optimum
  133. case n <= math.MaxUint16:
  134. return IsPrimeUint16(uint16(n))
  135. case n <= math.MaxUint32:
  136. return ProbablyPrimeUint32(uint32(n), 11000544) &&
  137. ProbablyPrimeUint32(uint32(n), 31481107)
  138. case n < 105936894253:
  139. return ProbablyPrimeUint64_32(n, 2) &&
  140. ProbablyPrimeUint64_32(n, 1005905886) &&
  141. ProbablyPrimeUint64_32(n, 1340600841)
  142. case n < 31858317218647:
  143. return ProbablyPrimeUint64_32(n, 2) &&
  144. ProbablyPrimeUint64_32(n, 642735) &&
  145. ProbablyPrimeUint64_32(n, 553174392) &&
  146. ProbablyPrimeUint64_32(n, 3046413974)
  147. case n < 3071837692357849:
  148. return ProbablyPrimeUint64_32(n, 2) &&
  149. ProbablyPrimeUint64_32(n, 75088) &&
  150. ProbablyPrimeUint64_32(n, 642735) &&
  151. ProbablyPrimeUint64_32(n, 203659041) &&
  152. ProbablyPrimeUint64_32(n, 3613982119)
  153. default:
  154. return ProbablyPrimeUint64_32(n, 2) &&
  155. ProbablyPrimeUint64_32(n, 325) &&
  156. ProbablyPrimeUint64_32(n, 9375) &&
  157. ProbablyPrimeUint64_32(n, 28178) &&
  158. ProbablyPrimeUint64_32(n, 450775) &&
  159. ProbablyPrimeUint64_32(n, 9780504) &&
  160. ProbablyPrimeUint64_32(n, 1795265022)
  161. }
  162. }
  163. // NextPrime returns first prime > n and true if successful or an undefined value and false if there
  164. // is no next prime in the uint32 limits. Typical run time is about 2 µs.
  165. //
  166. //TODO rename to NextPrimeUint32
  167. func NextPrime(n uint32) (p uint32, ok bool) {
  168. switch {
  169. case n < 65521:
  170. p16, _ := NextPrimeUint16(uint16(n))
  171. return uint32(p16), true
  172. case n >= math.MaxUint32-4:
  173. return
  174. }
  175. n++
  176. var d0, d uint32
  177. switch mod := n % 6; mod {
  178. case 0:
  179. d0, d = 1, 4
  180. case 1:
  181. d = 4
  182. case 2, 3, 4:
  183. d0, d = 5-mod, 2
  184. case 5:
  185. d = 2
  186. }
  187. p = n + d0
  188. if p < n { // overflow
  189. return
  190. }
  191. for {
  192. if IsPrime(p) {
  193. return p, true
  194. }
  195. p0 := p
  196. p += d
  197. if p < p0 { // overflow
  198. break
  199. }
  200. d ^= 6
  201. }
  202. return
  203. }
  204. // NextPrimeUint64 returns first prime > n and true if successful or an undefined value and false if there
  205. // is no next prime in the uint64 limits. Typical run time is in hundreds of µs.
  206. func NextPrimeUint64(n uint64) (p uint64, ok bool) {
  207. switch {
  208. case n < 65521:
  209. p16, _ := NextPrimeUint16(uint16(n))
  210. return uint64(p16), true
  211. case n >= 18446744073709551557: // last uint64 prime
  212. return
  213. }
  214. n++
  215. var d0, d uint64
  216. switch mod := n % 6; mod {
  217. case 0:
  218. d0, d = 1, 4
  219. case 1:
  220. d = 4
  221. case 2, 3, 4:
  222. d0, d = 5-mod, 2
  223. case 5:
  224. d = 2
  225. }
  226. p = n + d0
  227. if p < n { // overflow
  228. return
  229. }
  230. for {
  231. if ok = IsPrimeUint64(p); ok {
  232. break
  233. }
  234. p0 := p
  235. p += d
  236. if p < p0 { // overflow
  237. break
  238. }
  239. d ^= 6
  240. }
  241. return
  242. }
  243. // FactorTerm is one term of an integer factorization.
  244. type FactorTerm struct {
  245. Prime uint32 // The divisor
  246. Power uint32 // Term == Prime^Power
  247. }
  248. // FactorTerms represent a factorization of an integer
  249. type FactorTerms []FactorTerm
  250. // FactorInt returns prime factorization of n > 1 or nil otherwise.
  251. // Resulting factors are ordered by Prime. Typical run time is few µs.
  252. func FactorInt(n uint32) (f FactorTerms) {
  253. switch {
  254. case n < 2:
  255. return
  256. case IsPrime(n):
  257. return []FactorTerm{{n, 1}}
  258. }
  259. f, w := make([]FactorTerm, 9), 0
  260. for p := 2; p < len(primes16); p += int(primes16[p]) {
  261. if uint(p*p) > uint(n) {
  262. break
  263. }
  264. power := uint32(0)
  265. for n%uint32(p) == 0 {
  266. n /= uint32(p)
  267. power++
  268. }
  269. if power != 0 {
  270. f[w] = FactorTerm{uint32(p), power}
  271. w++
  272. }
  273. if n == 1 {
  274. break
  275. }
  276. }
  277. if n != 1 {
  278. f[w] = FactorTerm{n, 1}
  279. w++
  280. }
  281. return f[:w]
  282. }
  283. // PrimorialProductsUint32 returns a slice of numbers in [lo, hi] which are a
  284. // product of max 'max' primorials. The slice is not sorted.
  285. //
  286. // See also: http://en.wikipedia.org/wiki/Primorial
  287. func PrimorialProductsUint32(lo, hi, max uint32) (r []uint32) {
  288. lo64, hi64 := int64(lo), int64(hi)
  289. if max > 31 { // N/A
  290. max = 31
  291. }
  292. var f func(int64, int64, uint32)
  293. f = func(n, p int64, emax uint32) {
  294. e := uint32(1)
  295. for n <= hi64 && e <= emax {
  296. n *= p
  297. if n >= lo64 && n <= hi64 {
  298. r = append(r, uint32(n))
  299. }
  300. if n < hi64 {
  301. p, _ := NextPrime(uint32(p))
  302. f(n, int64(p), e)
  303. }
  304. e++
  305. }
  306. }
  307. f(1, 2, max)
  308. return
  309. }