10 best rational approximations for pi

It’s easy to create rational approximations for π. Every time you write down π to a few decimal places, that’s a rational approximation. For example, 3.14 = 314/100. But that’s not the best approximation.

Think of the denominator of your fraction as something you have to buy. If you have enough budget to buy a three-digit denominator, then you’re better off buying 355/113 rather than 314/100 because the former is more accurate. The approximation 355/113 is accurate to 6 decimal places, whereas 314/100 is only accurate to 2 decimal places.

There’s a way to find the most economical rational approximations to π, or any other irrational number, using continued fractions. If you’re interested in details, see the links below.

Here are the 10 best rational approximations to π, found via continued fractions.

    | Fraction       | Decimals |
    | 3              |      0.8 |
    | 22/7           |      2.9 |
    | 333/106        |      4.1 |
    | 355/113        |      6.6 |
    | 103993/33102   |      9.2 |
    | 104348/33215   |      9.5 |
    | 208341/66317   |      9.9 |
    | 312689/99532   |     10.5 |
    | 833719/265381  |     11.1 |
    | 1146408/364913 |     11.8 |

If you only want to know the number of correct decimal places, ignore the fractional parts of the numbers in the Decimals column above. For example, 22/7 gives two correct decimal places. But it almost gives three. (Technically, the Decimals column gives the -log10 of the absolute error.)

In case you’re curious, here’s a plot of the absolute errors on a log scale.

Errors in rational approximations to pi

Related posts

8 thoughts on “10 best rational approximations for pi

  1. The decimals column is usually about 1 less than the total number of digits used in the numerator AND denominator.

  2. I note that the number of correct decimals is close to the total number of digits in each fraction. Not a coincidence I guess?

  3. I’d say it’s not entirely a coincidence. It isn’t important how big the numerator is (you can add any integer to a number and that won’t change the accuracy of any estimate). However, to a first approximation, we would expect the number of correct decimals to be close to twice the number of digits in the denominator.

    We might ask how accurately you can represent a random number X (let’s say Uniform [0, 1], since only the fractional part affects the accuracy of the estimate anyway) by a fraction with denominator at most N. There are roughly 3N^2 / pi^2, or 0.304 N^2, such fractions in [0, 1] (N^2/2 multiplied by the probability of two large integers being coprime). If these were uniformly distributed, the best one would approximate X with an error of at most pi^2 / 6N^2. Of course this is not the case. The actual situation is much more complicated, and we would expect the approximation to be worse because uniformly distributed numbers are optimal if you want to choose one to approximate an arbitrary number. I’m sure someone could do a more rigorous analysis and find out (at least asymptotically) the expected error of the best estimate; however, it is not surprising that the error is at least close to the order of N^2, which corresponds to twice as many correct digits as the number of digits in the denominator.

  4. I wrote a Haskell program that finds approximations for given constant. It generates lazy infinite list of lazy infinite sublists, each n-th sublist is approximation for precision n (n numbers after decimal point).

    approx constant = [
          (rnd x, rnd y, diff) | 
            y <- [1..],
            t <- [fl $ y * constant .. ceil $ y * constant],
            let x = fromIntegral t,
            let k = 1 / 10^p,
            let diff = abs(x / y - constant),
            diff < k
        ] | 
        p <- [1..]
        [rnd, fl, ceil] = map (toInteger .) [round, floor, ceiling]
    piApprox = (approx pi !!) 
    expApprox = (approx (exp 1) !!)
    main = do
     print "Approximations of pi with precision up to 5 digits" 
     print $ take 10 $ piApprox 5
     print "Approximations of e with precision up to 5 digits"
     print $ take 10 $ expApprox 5
     print "Approximations of pi with precision from 1 to 11 digits"
     print $ map (take 10) $ take 11 $ approx pi
  5. Well, an interesting aside. If one looks at ellipses with semi-major and semi-minor axes, one can come up with a list of prime numbers for which round(ellipse area) is NOT prime. The list is fairly sparse. That list begins 7, 113, 265381, 842468587426513207. You will see that corresponds to OEIS A086788. Those will be the prime denominators of rational approximations to Pi with ever improving accuracy.

  6. Here is one I derived from the arithmetic properties of number 37 and using them to compose the 355/113 ratio. I havent seen it any place else so please give credit if it is novel although it is just another way to write 355/113 but with a cool mnemonic and only using two digits:

    (3(3(33 + 2 + 2) + 22)/(3(33 + 2 + 2) + 2)

    Terms containing 3 are multiplied while terms containing 2 are added.

    Using more digits one can write it as:

    (9*37 + 24 – 2) / (3*37 + 2)

    Now look what changing a single sign does:

    (9*37 – 24 – 2) / (3*37 + 2)

    It gives a good approximation of e. Quite a coincidence.

  7. @Bill McEachen, I didn’t know that. Thank you.
    I was wondering where would be the next ice hockey stick figure from the following python program. The bottom of the stick figures goes like 7, 113, 33215, … (corresponding rationals are 22/7 , 355/113 , 104348/33215, …)

    from decimal import *
    from vpython import *

    graph(fast=False, width=800, height=600, title=’Increasingly better rational approximations of π‘,
    xtitle=’log10(denominator)’, ytitle=’log10(Absolute error)’)
    piRatio = gdots()
    getcontext().prec = 100
    pi100 = Decimal(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679)
    for i in range(1,10000000) :
    r = abs( round(Decimal(i)*pi100)/Decimal(i) – pi100)
    if r < best :
    best = r
    # print(round(Decimal(i)*pi100),"/",i,"=", round(Decimal(i)*pi100)/Decimal(i))

Comments are closed.