Я знаю, это звучит как домашнее задание, но это не так. В последнее время меня интересуют алгоритмы, используемые для выполнения определенных математических операций, таких как синус, квадратный корень и т. Д. В настоящее время я пытаюсь написать вавилонский метод вычисления квадратных корней в 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 ()?» ... Я делаю это в качестве учебного упражнения и не собираюсь фактически использовать этот метод в любом производственном коде.