excellent ! (note that your did not include the function header "function f(x)" and trailer "end" and the code "=x" to print the result on the Lua console).
It works because the range from 0 to 395 is small enough and it assumes that math.random() will return an exact value.
This can create an infinite loop if this condition x*x=C is never reached exactly, because:
- random() will not explore all the possible bits, as random() does not return all the possible values for the 52 bits of numbers in (0,1).
- even if you have the best approximation possible of x, x^x=C may still be wrong (and there's no upper bound of the relative error on the value of x).
So let's assume that random() is able to generate at least 31 bits of precision with a resonably flat distribution, the exact value of log2(x^x) may be different from log2(C) by a relative factor of up to 15.5*x
i.e. you must stop the loop when log2(x^x)/log2(C) <= 15.5*x,
i.e. equivalently when ln(x^x)/ln(C)/15.5 <= x
or when ln(x^x)/x <= 15.5*ln(C)
You can see here why 15.5 is used in the problem, it's not "magic" but it's log2(31)
----
And why using random(), which is unnecessarily slow ?
We could just enumerate the 31 bits of precision in the open range (from 3.0 to 395.0). And this exploration can be much faster if you have a starting approximate (but lower) bound of the solution so that it will enumerate from a better start position (in which case it will require much less loops to reach the best lower bound that matches the expected precision of the result.
What is needed is only to estimate the lower bound of the base-2 integral exponent of x.
Interestingly, we have : x= 1024/log_2(x) so log_2(x)=1024/x
This allows starting the "for" loop to explore the 31 bits of precision of values of x (from 3.0 to 395.0) at a known integer position which is (1024 div x).
You just need an integer "for" loop (and your loop will not explore bits for very long because you are quite near from the expected precision at the start !).
Lets say that (exponent=1024 div x) is the starting value for your integer for-loop, the for-loop will run for at most log2(exponent), and given that exponent is below 1024, it will never run for more than 10 times (and 5 times on average)... and it is warrantied to give a correct result of x with at last 31 bits of precision.
now the 10 loops can be easily unrolled into inline code performing successive tests. But an even better solution is to perform a binary search in the small constant table of 10 constant values.