You don't need to discriminate to do it, as mentioned in comments below about continued fractions.
In brief, π can be represented as a stream of integers,
[ 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, 1, 4, 2, 6,
6, 99, 1, 2, 2,
6, 3, 5, 1, 1, 6,
8, 1, 7, 1, 2,
3, 7, 1, 2, 1,
1, 12, 1, 1, 1, 3,
1, 1, 8, 1, 1,
2, 1, 6, 1, 1,
5, 2, 2, 3, 1, 2,
4, 4, 16, 1, 161, ...]
To process into a rational approximation you want to maintain the two last aproximations a/b, c/d, and to get the first two numbers right you want to start with a/b = 0/1 and c/d = 1/0, zero and infinity.
When you come to a number N in the sequence you form the new rational approximation
(N*c + a)/(N*d + b).
So you absorb 3 to generate 3/1, then you absorb 7 to generate (3×7+1)/(7×1+0)=22/7, then you absorb 15 to generate (15×22 + 3)/(15×7 + 1) = 333/106, then you absorb 1 to get this magical approximation (333 + 22)/(106 + 7) = 355/113, etc.
In a sense what makes it magical is that the next number is very large. The larger it is the more decimal places you get “for free” truncating just before it. That is because this procedure is calculating the continued fraction
3 + 1/(7 + 1/(15 + 1/(1 + ...)))
And you can sort of see that when we fill in the “...” with 0 to truncate the expansion there, that is not so different from truncating it with 1/292 to truncate one step later or 1/293 to truncate two steps later. Those numbers are very close to zero!