primes.go 6.6 KB

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