Я знаю, это звучит как домашнее задание, но это не так. В последнее время меня интересуют алгоритмы, используемые для выполнения некоторых математических операций, таких как синус, квадратный корень и т. д. В данный момент я пытаюсь написать вавилонский метод вычисления квадратных корней в C#.
Пока что у меня это:
public static double SquareRoot(double x) {
if (x == 0) return 0;
double r = x / 2; // this is inefficient, but I can't find a better way
// to get a close estimate for the starting value of r
double last = 0;
int maxIters = 100;
for (int i = 0; i < maxIters; i++) {
r = (r + x / r) / 2;
if (r == last)
break;
last = r;
}
return r;
}
Он отлично работает и каждый раз дает точно такой же ответ, что и метод Math.Sqrt() .NET Framework. Однако, как вы, наверное, догадались, это медленнее, чем нативный метод (примерно на 800 тиков). Я знаю, что этот конкретный метод никогда не будет быстрее, чем собственный метод, но мне просто интересно, есть ли какие-либо оптимизации, которые я могу сделать.
Единственная оптимизация, которую я увидел сразу, заключалась в том, что расчет выполнялся 100 раз, даже после того, как ответ уже был определен (в этот момент r всегда будет одним и тем же значением). Итак, я добавил быструю проверку, чтобы увидеть, совпадает ли вновь вычисленное значение с ранее рассчитанным значением, и выйти из цикла. К сожалению, это не сильно повлияло на скорость, но просто казалось правильным поступить.
И прежде чем вы скажете: «Почему бы просто не использовать вместо этого Math.Sqrt()?»... Я делаю это в качестве учебного упражнения и не собираюсь фактически использовать этот метод в каком-либо производственном коде.