1
1
package expreduce
2
2
3
3
import (
4
+ "math"
4
5
"math/big"
5
6
6
7
"github.com/corywalker/expreduce/expreduce/atoms"
@@ -164,30 +165,43 @@ func getNumberTheoryDefinitions() (defs []Definition) {
164
165
& SameTest {"3" , "PrimePi[6.9]" },
165
166
},
166
167
})
167
- /* defs = append(defs, Definition{
168
- Name: "Prime",
169
- Usage: "`Prime[n]` returns the `n`th prime number.",
168
+ defs = append (defs , Definition {
169
+ Name : "Prime" ,
170
+ Usage : "`Prime[n]` returns the `n`th prime number." ,
170
171
Attributes : []string {"Listable" },
171
- legacyEvalFn: func(this *Expression , es *EvalState) Ex {
172
- if len(this.Parts ) != 2 {
172
+ legacyEvalFn : func (this expreduceapi. ExpressionInterface , es expreduceapi. EvalStateInterface ) expreduceapi. Ex {
173
+ if len (this .GetParts () ) != 2 {
173
174
return this
174
175
}
175
- asInt, isInt := this.Parts [1].(*Integer)
176
+ asInt , isInt := this .GetParts () [1 ].(* atoms. Integer )
176
177
if ! isInt {
177
178
return this
178
179
}
179
180
n := asInt .Val .Int64 ()
180
181
if n <= 0 {
181
182
return this
182
183
}
183
- p := prime.Primes(uint64(n))
184
- //return &Integer{big.NewInt(0)}
185
- // A hack to get this working would be to find an upper bound on
186
- // the PrimePi funciton given an n value, and use that as the input
187
- // to the Primes() function. Then I can directly select the nth
188
- // value from the slice. See:
189
- // https://math.stackexchange.com/questions/479798/estimating-the-upper-bound-of-prime-count-in-the-given-range
190
- return &Integer{big.NewInt(int64(p[len(p)-1]))}
184
+ // (Solve[n*(Log[n]+Log[Log[n]])==2^63,n, Reals][[1,1,2]]//N//Floor)-1000
185
+ if n > 211642827166041848 {
186
+ // Large numbers are not supported yet due to lack of big integer support.
187
+ return this
188
+ }
189
+ floatN := float64 (n )
190
+ // https://math.stackexchange.com/questions/1270814/bounds-for-n-th-prime
191
+ upperBound := floatN * (math .Log (floatN ) + math .Log (math .Log (floatN )))
192
+ if n < 6 {
193
+ upperBound = 11
194
+ }
195
+ // There is a bug in prime.Primes where the csegPool uses a stale segSize when
196
+ // we call the function for increasing values. For example, prime.Primes(15)
197
+ // and prime.Primes(19) will trigger the issue. To bypass this issue, use the
198
+ // slower function that doesn't have the problem, in the future, we could
199
+ // consider fixing this.
200
+ // Lines with the bug:
201
+ // https://github.com/kavehmz/prime/blob/a94ad56341db886ae3346de1e6b341387c3c01d3/prime.go#L110-L112
202
+ // Reproduced the issue at: https://github.com/corywalker/prime/commit/efd80a4fe9efd7263b329006629855d6f73c1c2e
203
+ p := prime .SieveOfEratosthenes (uint64 (upperBound ) + 1 )
204
+ return atoms .NewInteger (big .NewInt (int64 (p [n - 1 ])))
191
205
},
192
206
SimpleExamples : []TestInstruction {
193
207
& SameTest {"5" , "Prime[3]" },
@@ -197,8 +211,10 @@ func getNumberTheoryDefinitions() (defs []Definition) {
197
211
& SameTest {"Prime[0]" , "Prime[0]" },
198
212
& SameTest {"Prime[1.]" , "Prime[1.]" },
199
213
& SameTest {"2" , "Prime[1]" },
214
+ // Large numbers should remain unevaluated due to overflow risk.
215
+ & SameTest {"Prime" , "Prime[2^64]//Head" },
200
216
},
201
- })*/
217
+ })
202
218
defs = append (defs , Definition {Name : "EvenQ" })
203
219
defs = append (defs , Definition {Name : "OddQ" })
204
220
defs = append (defs , Definition {Name : "FactorInteger" })
0 commit comments