Inspired by This answer to a Puzzling question
Background - exponentiation by squaring
If you don't want to read the background, or don't understand it, there's a worked example in Java, linked at the bottom of the post.
\$a^{2^{x+1}} = a^{2^{x}} * a^{2^{x}}\$
Therefore to find \$a^b\$ (where \$a\$ and \$b\$ are base-10 numbers), you can use the following steps:
(using the example: \$a^b = 3^{2020} = 6.0944502154628860109199404161593e+963\$)
- Convert \$b\$ to binary (\$2020\$ -> \$11111100100\$)
- For each \$1\$ in the binary (\$n\$), calculate \$a^n\$, by starting at \$a^1\$ and repeatedly squaring to get \$a^2\$, \$a^4\$, etc... and keeping only those numbers we need (\$3^1 = 3\$, \$3^2 = 9\$, squared gives \$3^4 = 81\$, squared gives \$3^8 = 6561\$, squared gives \$3^{16} = 43046721\$, squared gives \$3^{32} = 1853020188851841\$, etc. We just keep those numbers where the binary mask is a 1.)
- Multiply all the kept answers from step 2 where the binary mask is a \$1\$ (\$81*1853020188851841*...\$).
- The first non-zero digit is therefore \$6\$.
The problem with this method though, even though it is easier for humans than calculating such a large exponent straight-off, is that you still have to square some pretty large numbers.
In Theory, though, we can approximate!
According to the link at the start of the question, you can approximate by just considering the first \$n\$ digits (rounded) at each stage in step 2 above - with larger \$n\$ giving a lower margin of error.
For example, if \$n=4\$, then you get* \$3^2=9,^2=81,^2=6561,^2\approx4305,^2\approx1853,^2\approx3434,^2\approx1179,^2\approx1390,^2\approx1932,^2\approx3733\$.
note that the numbers here have been rounded*, rather than just truncated - e.g. 6561 * 6561 = 43046721 - which has been rounded to 4305 rather than 4304.
Keeping \$3733,1932,1390,1179,3434,1853,81\$ from the bitmask we can then do \$3733*1932*1390*1179*3434*1853*81= 6091923575465178358320\$, so the first digit is \$6\$, as we would expect.
This is not only easier in our heads, but it gives us the same first digit! Much simpler!
However, if we only consider the first \$3\$ digits when we double, instead of the first \$4\$, we get \$353*188*137*117*342*185*81 = 5451573062187720\$, which gives us a first digit of \$5\$ instead of \$6\$ - that's why it's only approximately accurate!
The Challenge is to find the first digit of \$a^b\$, where only the first \$n\$ digits, rounded, are considered each time we square. You don't have to use exponentiation by squaring in your program, if you can get the correct answers by another method.
Inputs
Three positive Integers (greater than \$0\$), up to an arbitrary maximum (your program should work in theory for all possible Integers) - the base \$a\$, the exponent \$b\$ and the approximation length \$n\$
Output
a single digit or character in the range [1..9]
Some Worked Examples
3,2020,3 -> 5 (see worked example in background above)
3,2020,4 -> 6 (see worked example in background above)
2,20,1 -> \$20_{10} = 10100_2. 2^1=2,^2=4,^2=16\approx2,^2=4,^2=16\approx2\$ which gives \$2^{16}*2^4\approx2*2\$ = 4
2,20,2 -> \$2^1=2,^2=4,^2=16,^2=256\approx26,^2=676\approx68\$ which gives \$68*16 = 1088\$, first digit 1
2,20,3 -> \$2^1=2,^2=4,^2=16,^2=256,^2=65536\approx655\$ which gives \$655*16 = 10480\$, first digit 1
2,20,4 -> \$6554*16 = 104864\$, first digit 1
2,20,5 or above -> \$65536*16 = 1048576\$, first digit 1
15,127,5 -> 15,225,50625,25629...,65685...,43145...,18615... -> 231009687490539279462890625 -> 2
The same Examples formatted for easy copying, plus some additional ones
a,b,n,outputs result 3,2020,3 outputs 5 3,2020,4 outputs 6 3,2020,5 outputs 6 2,20,1 outputs 4 2,20,2 outputs 1 2,20,3 outputs 1 2,20,4 outputs 1 2,20,5 outputs 1 2,20,6 outputs 1 2,11111,4 outputs 5 4,1234,3 outputs 8 5,54,2 outputs 6 6,464,3 outputs 1 7,2202,4 outputs 8 8,1666,5 outputs 3 9,46389,6 outputs 2 10,1234,7 outputs 1 11,5555,8 outputs 8 12,142,14 outputs 1 This is code-golf, usual rules and restrictions apply, lowest bytes wins.
EDIT
*to clarify what I mean by rounding, any number less than \$x.5\$ should round down to \$x\$. Any number greater than \$x.5\$ should round up to \$x+1\$. The boundary (\$x.5\$) can go either way, depending on your language.
getFirstCharacterApproximatelyfunction:BigInteger.valueOf(Long.parseLong(fullCurrentPowerString.substring(0, Math.min(fullCurrentPowerString.length(), n+1))));:) \$\endgroup\$