Find the 5566th digit after the decimal point of 7/101
Fast algorithm
n = 5566
IntegerPart[10 Mod[7 PowerMod[10, n - 1, 101], 101]/101]
A brute force approach (see also these posts on stackoverflow :) ) may
be fine for the current problem, but what if n
is a huge number? The only possibility apart from guessing the periodic sequence of numbers as mgamer suggested would be to use modular arithmetics. Let me explain my answer. In contrast to the original post we put the number of interest not in the last digit of the integer part, but in the first digit of the fractional part. Conveniently, the fractional part can be computed as a reminder, or for higher efficiency by PowerMod
.
Let us compare the timing of the two methods:
n = 556612345;
Mod[IntegerPart[7 10^n/101], 10] // Timing
(*{10.447660, 3}*)
IntegerPart[10 Mod[7 PowerMod[10, n - 1, 101], 101]/101] // Timing
(*{0.000016, 3}*)
The time difference is obvious!
Explanation
Let us consider another example, we compute the n=6
digit of the 7/121
fraction.
n = 6
N[7/121, 30]
0.0578512396694214876033057851240.
In the original post the sought digit is the last digit of the integer part:
N[7 10^n/121, 20]
57851.239669421487603
whereas in my solution it is the first digit in the fractional part
N[Mod[7*10^(n - 1), 121]/121, 20]
0.12396694214876033058 .
It is further used that Mod[a 10^b,c]=Mod[a PowerMod[10,b,c],c]
.
Reusable function
As requested in the comments, a reusable function can be provided:
Clear[nthDigitFraction];
nthDigitFraction[numerator_Integer, denominator_Integer, n_Integer,
base_Integer: 10] /; n > 0 && base > 0 && denominator != 0 :=
Module[{a = Abs[numerator], b = Abs[denominator]},
IntegerPart[base Mod[a PowerMod[base, n - 1, b], b]/b]]
An alternative formulation of RealDigits
that I prefer:
RealDigits[7/101, 10, 1, -5566][[1, 1]]
(* 6 *)
This yields better performance which becomes important when looking for deeper digits:
d = 6245268;
RealDigits[7/101, 10, 1, -d][[1, 1]] // AbsoluteTiming
RealDigits[7/101, 10, d - 1][[1, -1]] // AbsoluteTiming
{0.0501477, 3} {1.06702, 3}
Recommended reading:
- Does Mathematica get Pi wrong?
For comparison to other methods now posted RealDigits
can compute the repeating decimal itself:
RealDigits[7/101]
{{{6, 9, 3, 0}}, -1}
How to programmatically work with this output was the subject of a different Question, though I cannot find it at the moment. The possible combinations of repeating and nonrepeating digits as well as the offset makes a truly elegant yet robust solution difficult (at least to me) but in the easiest case, which this happens to be:
d = 5566;
RealDigits[7/101] /.
{{c_List}, o_} :>
c[[ Mod[d + o, Length @ c, 1] ]]
(* 6 *)
This is of course quite fast:
d = 556612345;
RealDigits[7/101] /.
{{c_List}, o_} :> c[[ Mod[d + o, Length@c, 1] ]] // RepeatedTiming
{0.00001243, 0}
Use RealDigits
RealDigits[7/101, 10, 5566][[1]][[5565]]