I don't have time for a full answer, but here is a partial answer. This technique uses the concepts of continued fractions--there is much about them online. I'll ignore your value dmin, which is not used below.
Get the continued fraction expansion of pi to as many places as you need. For your bound of dmax <= 1e15 you need only the first 28 numbers, which are
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, 15, 3, 13]
Use a short loop to find the convergents for pi that have denominators just below and just above dmax. In Python that would be
pi_cont_frac = [3, 7, 15, 1, 292, 1, 1, 1, 2, 1,
3, 1, 14, 2, 1, 1, 2, 2, 2, 2,
1, 84, 2, 1, 1, 15, 3, 13]
denomlo, denomhi = 1, 0
numlo, numhi = 0, 1
for q in pi_cont_frac:
denomlo, denomhi = denomhi, q * denomhi + denomlo
numlo, numhi = numhi, q * numhi + numlo
if denomhi > dmax:
break
Some software, such as Microsoft Excel, would use the fraction numlo/denomlo
, but there may be better approximation than that. Now find the value of natural number r that makes denomhi - r * denomlo
just below (or equal to) dmax.
Then either numlo/denomlo
or (denomhi - r * denomlo)/(denomhi - r * denomlo)
is your desired closest fraction to pi. Just check which one is closer.
This algorithm is of order log(dmax), and due to the properties of pi it is usually much lower. For dmax <= 1e15 it takes 28 loops but a few more clean-up statements.
You could make a faster algorithm by pre-calculating and storing the convergents (values of numhi and denomhi) and doing a search for the value of denomhi just above dmax. This also only takes 28 numbers, but you would need this for both the numerators and the denominators. A binary search would take at most 5 steps to find it--practically instantaneous. Yet another possibility using more storage and less calculation would be to store all intermediate fractions. That storage would go into the hundreds, at least three hundred. If you don't like that stored list for the continued fraction expansion of pi, you could use the value of pi to calculate that on the fly, but using double precision (in C) would get you only to the 28 numbers I showed you.
For more research, look up continued fractions and intermediate fractions.