Skip to content

Commit

Permalink
- Added the Number n.prime_lower and n.prime_upper methods.
Browse files Browse the repository at this point in the history
Lower and upper bounds for the n-th prime.

Example:

	say 1e12.prime_lower		#=> 29996219470245
	say 1e12.prime_upper		#=> 29996230936979

	say 1e12.prime			#=> 29996224275833  (exact value)
  • Loading branch information
trizen committed Jun 21, 2021
1 parent 8ece881 commit 9df78d7
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 5 deletions.
91 changes: 87 additions & 4 deletions lib/Sidef/Types/Number/Number.pm
Original file line number Diff line number Diff line change
Expand Up @@ -10022,6 +10022,11 @@ package Sidef::Types::Number::Number {
CORE::int($n * (CORE::log($n) + CORE::log(CORE::log($n)) - 1));
}

sub _nth_prime_upper {
my ($n) = @_;
CORE::int($n * (CORE::log($n) + CORE::log(CORE::log($n))));
}

sub _nth_almost_prime_lower {
my ($n, $k) = @_;

Expand Down Expand Up @@ -10494,19 +10499,97 @@ package Sidef::Types::Number::Number {
*count_primes = \&prime_count;

sub prime_count_lower {
my $prime_pi = Math::Prime::Util::GMP::prime_count_lower(&_big2uistr // return ZERO) // 0;
_set_int($prime_pi);
my ($n) = @_;

$n = _any2mpz($$n) // return ZERO;

if (Math::GMPz::Rmpz_sgn($n) <= 0) {
return ZERO;
}

if (HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($n)) {
return _set_int(Math::Prime::Util::prime_count_lower(Math::GMPz::Rmpz_get_ui($n)));
}

_set_int(Math::Prime::Util::GMP::prime_count_lower(Math::GMPz::Rmpz_get_str($n, 10)));
}

*primepi_lower = \&prime_count_lower;

sub prime_count_upper {
my $prime_pi = Math::Prime::Util::GMP::prime_count_upper(&_big2uistr // return ZERO) // 0;
_set_int($prime_pi);
my ($n) = @_;

$n = _any2mpz($$n) // return ZERO;

if (Math::GMPz::Rmpz_sgn($n) <= 0) {
return ZERO;
}

if (HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($n)) {
return _set_int(Math::Prime::Util::prime_count_upper(Math::GMPz::Rmpz_get_ui($n)));
}

_set_int(Math::Prime::Util::GMP::prime_count_upper(Math::GMPz::Rmpz_get_str($n, 10)));
}

*primepi_upper = \&prime_count_upper;

sub _nth_prime_lower_bound {
my ($n) = @_;
my $log_n = $n->log;
$n->mul($log_n->add($log_n->log)->dec);
}

sub _nth_prime_upper_bound {
my ($n) = @_;
my $log_n = $n->log;
$n->mul($log_n->add($log_n->log));
}

sub nth_prime_lower {
my ($n) = @_;

my $z = _any2mpz($$n) // goto &nan;

if (Math::GMPz::Rmpz_cmp_ui($z, 10) <= 0) {
return $n->nth_prime;
}

bsearch_min(
$n->_nth_prime_lower_bound,
$n->_nth_prime_upper_bound,
Sidef::Types::Block::Block->new(
code => sub {
$_[0]->prime_count_upper->cmp($n);
}
)
);
}

*prime_lower = \&nth_prime_lower;

sub nth_prime_upper {
my ($n) = @_;

my $z = _any2mpz($$n) // goto &nan;

if (Math::GMPz::Rmpz_cmp_ui($z, 10) <= 0) {
return $n->nth_prime;
}

bsearch_max(
$n->_nth_prime_lower_bound,
$n->_nth_prime_upper_bound,
Sidef::Types::Block::Block->new(
code => sub {
$_[0]->prime_count_lower->cmp($n);
}
)
);
}

*prime_upper = \&nth_prime_upper;

sub almost_prime_count {
my ($k, $from, $to) = @_;

Expand Down
22 changes: 21 additions & 1 deletion lib/Sidef/Types/Number/Number.pod
Original file line number Diff line number Diff line change
Expand Up @@ -5169,6 +5169,16 @@ Returns the unique prime factors of C<n>.

=cut

=head2 prime_lower

n.prime_lower

Lower bound for the n-th prime.

Aliases: I<nth_prime_lower>

=cut

=head2 primepi

primepi(n)
Expand Down Expand Up @@ -5345,14 +5355,24 @@ Aliases: I<primes_sum>, I<sum_primes>

=head2 prime_udivisors

n.prime_udivisors()
n.prime_udivisors

Returns the unique unitary prime factors of C<n>.

Aliases: I<prime_unitary_divisors>, I<unitary_prime_divisors>

=cut

=head2 prime_upper

n.prime_upper

Upper bound for the n-th prime.

Aliases: I<nth_prime_upper>

=cut

=head2 prime_usigma

n.prime_usigma(k=1)
Expand Down

0 comments on commit 9df78d7

Please sign in to comment.