Написание собственной функции квадратного корня

Как вы пишете свою собственную функцию для нахождения наиболее точного квадратного корня целого числа?

После поиска в Интернете я нашел this (заархивирован из исходной ссылки ), но во-первых, я не получил его полностью, во-вторых, он также приблизительный.

Предположим, что квадратный корень является ближайшим целым числом (до фактического корня) или поплавком.

Ответ 1

Следующий вычислительный пол (sqrt (N)) для N > 0:

x = 2^ceil(numbits(N)/2)
loop:
    y = floor((x + floor(N/x))/2)
    if y >= x
        return x
    x = y

Это версия метода Ньютона, приведенная в Крэндалле и Померансе, "Prime Numbers: Computational Perspective". Причина, по которой вы должны использовать эту версию, состоит в том, что люди, которые знают, что делают, доказали, что они сходятся точно до пола квадратного корня, и это просто, поэтому вероятность выполнения ошибки реализации мала. Это также быстро (хотя возможно построить еще более быстрый алгоритм, но делать это правильно намного сложнее). Правильно реализованный двоичный поиск может быть быстрее для очень маленького N, но там вы также можете использовать таблицу поиска.

Чтобы округлить до ближайшего целого числа, просто вычислите t = floor (sqrt (4N)) с использованием вышеприведенного алгоритма. Если установлен младший значащий бит t, выберите x = (t + 1)/2; в противном случае выберите t/2. Обратите внимание, что это округляется на галстуке; вы также можете округлить (или округлить до четности), посмотрев, отличен ли остаток от нуля (т.е. t ^ 2 == 4N).

Обратите внимание, что вам не нужно использовать арифметику с плавающей запятой. На самом деле, вы не должны. Этот алгоритм должен быть полностью реализован с использованием целых чисел (в частности, функции floor() просто указывают, что должно использоваться регулярное целочисленное деление).

Ответ 2

В зависимости от ваших потребностей может быть использована простая стратегия разделения и побед. Он не будет сходиться так же быстро, как некоторые другие методы, но для новичков это может быть намного легче понять. Кроме того, поскольку он является алгоритмом O (log n) (вдвое сокращая пространство поиска на каждой итерации), наихудшим случаем для 32-битного поплавка будет 32 итерации.

Скажем, вам нужен квадратный корень из 62.104. Вы выбираете значение на полпути между 0 и этим и округлите его. Если квадрат выше вашего номера, вам нужно сосредоточиться на числах меньше, чем в средней точке. Если он слишком низко, сосредоточьтесь на тех, кто выше.

С реальной математикой вы могли бы разделить пространство поиска на два навсегда (если у него нет рационального квадратного корня). На самом деле компьютеры в конечном итоге исчерпывают точность, и у вас будет ваше приближение. Следующая программа C иллюстрирует точку:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) {
    float val, low, high, mid, oldmid, midsqr;
    int step = 0;

    // Get argument, force to non-negative.

    if (argc < 2) {
        printf ("Usage: sqrt <number>\n");
        return 1;
    }
    val = fabs (atof (argv[1]));

    // Set initial bounds and print heading.

    low = 0;
    high = mid = val;
    oldmid = -1;

    printf ("%4s  %10s  %10s  %10s  %10s  %10s    %s\n",
        "Step", "Number", "Low", "High", "Mid", "Square", "Result");

    // Keep going until accurate enough.

    while (fabs(oldmid - mid) >= 0.00001) {
        oldmid = mid;

        // Get midpoint and see if we need lower or higher.

        mid = (high + low) / 2;
        midsqr = mid * mid;
        printf ("%4d  %10.4f  %10.4f  %10.4f  %10.4f  %10.4f  ",
            ++step, val, low, high, mid, midsqr);
        if (mid * mid > val) {
            high = mid;
            printf ("- too high\n");
        } else {
            low = mid;
            printf ("- too low\n");
        }
    }

    // Desired accuracy reached, print it.

    printf ("sqrt(%.4f) = %.4f\n", val, mid);
    return 0;
}

Вот несколько прогонов, чтобы вы, надеюсь, поняли, как это работает. Для 77:

pax> sqrt 77
Step      Number         Low        High         Mid      Square    Result
   1     77.0000      0.0000     77.0000     38.5000   1482.2500  - too high
   2     77.0000      0.0000     38.5000     19.2500    370.5625  - too high
   3     77.0000      0.0000     19.2500      9.6250     92.6406  - too high
   4     77.0000      0.0000      9.6250      4.8125     23.1602  - too low
   5     77.0000      4.8125      9.6250      7.2188     52.1104  - too low
   6     77.0000      7.2188      9.6250      8.4219     70.9280  - too low
   7     77.0000      8.4219      9.6250      9.0234     81.4224  - too high
   8     77.0000      8.4219      9.0234      8.7227     76.0847  - too low
   9     77.0000      8.7227      9.0234      8.8730     78.7310  - too high
  10     77.0000      8.7227      8.8730      8.7979     77.4022  - too high
  11     77.0000      8.7227      8.7979      8.7603     76.7421  - too low
  12     77.0000      8.7603      8.7979      8.7791     77.0718  - too high
  13     77.0000      8.7603      8.7791      8.7697     76.9068  - too low
  14     77.0000      8.7697      8.7791      8.7744     76.9893  - too low
  15     77.0000      8.7744      8.7791      8.7767     77.0305  - too high
  16     77.0000      8.7744      8.7767      8.7755     77.0099  - too high
  17     77.0000      8.7744      8.7755      8.7749     76.9996  - too low
  18     77.0000      8.7749      8.7755      8.7752     77.0047  - too high
  19     77.0000      8.7749      8.7752      8.7751     77.0022  - too high
  20     77.0000      8.7749      8.7751      8.7750     77.0009  - too high
  21     77.0000      8.7749      8.7750      8.7750     77.0002  - too high
  22     77.0000      8.7749      8.7750      8.7750     76.9999  - too low
  23     77.0000      8.7750      8.7750      8.7750     77.0000  - too low
sqrt(77.0000) = 8.7750

Для 62.104:

pax> sqrt 62.104
Step      Number         Low        High         Mid      Square    Result
   1     62.1040      0.0000     62.1040     31.0520    964.2267  - too high
   2     62.1040      0.0000     31.0520     15.5260    241.0567  - too high
   3     62.1040      0.0000     15.5260      7.7630     60.2642  - too low
   4     62.1040      7.7630     15.5260     11.6445    135.5944  - too high
   5     62.1040      7.7630     11.6445      9.7037     94.1628  - too high
   6     62.1040      7.7630      9.7037      8.7334     76.2718  - too high
   7     62.1040      7.7630      8.7334      8.2482     68.0326  - too high
   8     62.1040      7.7630      8.2482      8.0056     64.0895  - too high
   9     62.1040      7.7630      8.0056      7.8843     62.1621  - too high
  10     62.1040      7.7630      7.8843      7.8236     61.2095  - too low
  11     62.1040      7.8236      7.8843      7.8540     61.6849  - too low
  12     62.1040      7.8540      7.8843      7.8691     61.9233  - too low
  13     62.1040      7.8691      7.8843      7.8767     62.0426  - too low
  14     62.1040      7.8767      7.8843      7.8805     62.1024  - too low
  15     62.1040      7.8805      7.8843      7.8824     62.1323  - too high
  16     62.1040      7.8805      7.8824      7.8815     62.1173  - too high
  17     62.1040      7.8805      7.8815      7.8810     62.1098  - too high
  18     62.1040      7.8805      7.8810      7.8807     62.1061  - too high
  19     62.1040      7.8805      7.8807      7.8806     62.1042  - too high
  20     62.1040      7.8805      7.8806      7.8806     62.1033  - too low
  21     62.1040      7.8806      7.8806      7.8806     62.1038  - too low
  22     62.1040      7.8806      7.8806      7.8806     62.1040  - too high
  23     62.1040      7.8806      7.8806      7.8806     62.1039  - too high
sqrt(62.1040) = 7.8806

Для 49:

pax> sqrt 49
Step      Number         Low        High         Mid      Square    Result
   1     49.0000      0.0000     49.0000     24.5000    600.2500  - too high
   2     49.0000      0.0000     24.5000     12.2500    150.0625  - too high
   3     49.0000      0.0000     12.2500      6.1250     37.5156  - too low
   4     49.0000      6.1250     12.2500      9.1875     84.4102  - too high
   5     49.0000      6.1250      9.1875      7.6562     58.6182  - too high
   6     49.0000      6.1250      7.6562      6.8906     47.4807  - too low
   7     49.0000      6.8906      7.6562      7.2734     52.9029  - too high
   8     49.0000      6.8906      7.2734      7.0820     50.1552  - too high
   9     49.0000      6.8906      7.0820      6.9863     48.8088  - too low
  10     49.0000      6.9863      7.0820      7.0342     49.4797  - too high
  11     49.0000      6.9863      7.0342      7.0103     49.1437  - too high
  12     49.0000      6.9863      7.0103      6.9983     48.9761  - too low
  13     49.0000      6.9983      7.0103      7.0043     49.0598  - too high
  14     49.0000      6.9983      7.0043      7.0013     49.0179  - too high
  15     49.0000      6.9983      7.0013      6.9998     48.9970  - too low
  16     49.0000      6.9998      7.0013      7.0005     49.0075  - too high
  17     49.0000      6.9998      7.0005      7.0002     49.0022  - too high
  18     49.0000      6.9998      7.0002      7.0000     48.9996  - too low
  19     49.0000      7.0000      7.0002      7.0001     49.0009  - too high
  20     49.0000      7.0000      7.0001      7.0000     49.0003  - too high
  21     49.0000      7.0000      7.0000      7.0000     49.0000  - too low
  22     49.0000      7.0000      7.0000      7.0000     49.0001  - too high
  23     49.0000      7.0000      7.0000      7.0000     49.0000  - too high
sqrt(49.0000) = 7.0000

Ответ 3

Простой (но не очень быстрый) метод вычисления квадратного корня из X:

squareroot(x)
    if x<0 then Error
    a = 1
    b = x
    while (abs(a-b)>ErrorMargin) 
        a = (a+b)/2
        b = x/a
    endwhile
    return a;

Пример: squareroot (70000)

    a       b
    1   70000
35001       2
17502       4
 8753       8
 4381      16
 2199      32
 1116      63
  590     119
  355     197
  276     254
  265     264

Как вы можете видеть, он определяет верхнюю и нижнюю границы для квадратного корня и сужает границу до тех пор, пока ее размер не будет приемлемым.

Существуют более эффективные методы, но это иллюстрирует процесс и его легко понять.

Просто будьте осторожны, чтобы установить Errormargin в 1, если вы используете целые числа, у вас есть бесконечный цикл.

Ответ 4

Позвольте мне указать на чрезвычайно интересный метод расчета обратного квадратного корня 1/sqrt (x), который является легендой в мире игрового дизайна, потому что он умудряется быстро. Или подождите, прочитайте следующее сообщение:

http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/

PS: Я знаю, что вам просто нужен квадратный корень, но изящество землетрясения преодолело все сопротивление с моей стороны:)

Кстати, в вышеупомянутой статье также говорится о скучном приближении Ньютона-Рафсона.

Ответ 5

Конечно, он приблизительный; вот как работает математика с числами с плавающей запятой.

В любом случае, стандартный способ заключается в методе Ньютона. Это примерно то же самое, что и с использованием серии Тейлора, что сразу приходит в голову.

Ответ 6

Вычислить квадратный корень с произвольной точностью в Python

#!/usr/bin/env python
import decimal

def sqrt(n):
    assert n > 0
    with decimal.localcontext() as ctx:
        ctx.prec += 2 # increase precision to minimize round off error
        x, prior = decimal.Decimal(n), None
        while x != prior: 
            prior = x
            x = (x + n/x) / 2 # quadratic convergence 
    return +x # round in a global context


decimal.getcontext().prec = 80 # desirable precision
r = sqrt(12345)
print r
print r == decimal.Decimal(12345).sqrt()

Вывод:

111.10805551354051124500443874307524148991137745969772997648567316178259031751676
True

Ответ 7

Найдена отличная статья о Целочисленные квадратные корни.

Это немного улучшенная версия, которую она представляет там:

unsigned long sqrt(unsigned long a){
    int i;
    unsigned long rem = 0;
    unsigned long root = 0;
    for (i = 0; i < 16; i++){
        root <<= 1;
        rem = (rem << 2) | (a >> 30);
        a <<= 2;
        if(root < rem){
            root++;
            rem -= root;
            root++;
        }
    }
    return root >> 1;
}

Ответ 8

Это общий вопрос для интервью, заданный Facebook и т.д. Я не думаю, что это хорошая идея использовать метод Ньютона в интервью. Что, если интервьюер спросит вас о механизме метода Ньютона, если вы этого не понимаете?

Я представил решение на основе двоичного поиска на Java, которое, как я считаю, каждый может понять.

public int sqrt(int x) {

    if(x < 0) return -1;
    if(x == 0 || x == 1) return x;

    int lowerbound = 1;
    int upperbound = x;
    int root = lowerbound + (upperbound - lowerbound)/2;

    while(root > x/root || root+1 <= x/(root+1)){
        if(root > x/root){
            upperbound = root;
        } else {
            lowerbound = root;
        }
        root = lowerbound + (upperbound - lowerbound)/2;
    }
    return root;
}

Вы можете проверить мой код здесь: leetcode: sqrt (x)

Ответ 9

Первое, что приходит мне на ум, - это хорошее место для использования бинарного поиска (вдохновленного этими великими учебниками).

Чтобы найти квадратный корень vaule, мы ищем number в (1..value) где предиктор является истинным в первый раз. Предиктором, который мы выбираем, является number * number - value > 0.00001.

double square_root_of(double value)
{
     assert(value >= 1);
     double lo = 1.0;
     double hi = value;

     while( hi - lo > 0.00001)
     {
          double mid = lo + (hi - lo) / 2 ;
          std::cout << lo << "," << hi << "," << mid << std::endl;
          if( mid * mid - value > 0.00001)    //this is the predictors we are using 
          {
              hi = mid;
          } else {
              lo = mid;
          }

     }

    return lo;
 }

Ответ 10

Существует алгоритм, который я изучил в школе, который вы можете использовать для вычисления точных квадратных корней (или произвольно большой точности, если корень является иррациональным числом). Это определенно медленнее, чем алгоритмы Ньютона, но это точно. Допустим, вы хотите вычислить квадратный корень из 531.3025

Прежде всего, вы разделите свой номер, начиная с десятичной точки, на группы из двух цифр:
{5} {31}. {30} {25}
Тогда:
1) Найдите ближайший квадратный корень для первой группы, который меньше или равен фактическому квадратному корню из первой группы: sqrt ({5}) >= 2. Этот квадратный корень является первой цифрой вашего окончательного ответа. Давайте обозначим цифры, которые мы уже нашли в нашем конечном квадратном корне, как B. Итак, в момент B = 2.
2) Затем вычислите разницу между {5} и B ^ 2: 5 - 4 = 1.
3) Для всех последующих двухзначных групп выполните следующие действия:
Умножьте остаток на 100, затем добавьте его ко второй группе: 100 + 31 = 131.
Найдите X - следующую цифру вашего корня, такую, что 131 >= ((B * 20) + X) * X. X = 3. 43 * 3 = 129 < 131. Теперь B = 23. Кроме того, потому что у вас больше двухзначных групп слева от десятичных точек, вы нашли все целые цифры вашего последнего корня.
4) Повторите то же самое для {30} и {25}. Итак, у вас есть:
{30}: 131 - 129 = 2. 2 * 100 + 30 = 230 >= (23 * 2 * 10 + X) * X → X = 0 → B = 23.0
{25}: 230 - 0 = 230. 230 * 100 + 25 = 23025. 23025 >= (230 * 2 * 10 + X) * X → X = 5 → B = 23.05
Конечный результат = 23.05.
Алгоритм выглядит сложным, но это намного проще, если вы делаете это на бумаге, используя ту же нотацию, которую используете для "длинного разделения", которую вы изучали в школе, за исключением того, что вы не занимаетесь делением, а вместо этого вычисляете квадратный корень.

Ответ 11

Здесь можно получить квадратный корень с использованием тригонометрии. Это не самый быстрый алгоритм с длинным ударом, но он точен. Код находится в javascript:

var n = 5; //number to get the square root of
var icr = ((n+1)/2); //intersecting circle radius
var sqrt = Math.cos(Math.asin((icr-1)/icr))*icr; //square root of n
alert(sqrt);

Ответ 12

// Fastest way I found, an (extreme) C# unrolled version of:
// http://www.hackersdelight.org/hdcodetxt/isqrt.c.txt         (isqrt4)

// It quite a lot of code, basically a binary search (the "if" statements)
// followed by an unrolled loop (the labels).
// Most important: it fast, twice as fast as "Math.Sqrt".
// On my pc: Math.Sqrt ~35 ns, sqrt <16 ns (mean <14 ns)

private static uint sqrt(uint x)
{
    uint y, z;
    if (x < 1u << 16)
    {
        if (x < 1u << 08)
        {
            if (x < 1u << 04) return x < 1u << 02 ? x + 3u >> 2 : x + 15u >> 3;
            else
            {
                if (x < 1u << 06)
                { y = 1u << 03; x -= 1u << 04; if (x >= 5u << 02) { x -= 5u << 02; y |= 1u << 02; } goto L0; }
                else
                { y = 1u << 05; x -= 1u << 06; if (x >= 5u << 04) { x -= 5u << 04; y |= 1u << 04; } goto L1; }
            }
        }
        else                                             // slower (on my pc): .... y = 3u << 04; } goto L1; }
        {
            if (x < 1u << 12)
            {
                if (x < 1u << 10)
                { y = 1u << 07; x -= 1u << 08; if (x >= 5u << 06) { x -= 5u << 06; y |= 1u << 06; } goto L2; }
                else
                { y = 1u << 09; x -= 1u << 10; if (x >= 5u << 08) { x -= 5u << 08; y |= 1u << 08; } goto L3; }
            }
            else
            {
                if (x < 1u << 14)
                { y = 1u << 11; x -= 1u << 12; if (x >= 5u << 10) { x -= 5u << 10; y |= 1u << 10; } goto L4; }
                else
                { y = 1u << 13; x -= 1u << 14; if (x >= 5u << 12) { x -= 5u << 12; y |= 1u << 12; } goto L5; }
            }
        }
    }
    else
    {
        if (x < 1u << 24)
        {
            if (x < 1u << 20)
            {
                if (x < 1u << 18)
                { y = 1u << 15; x -= 1u << 16; if (x >= 5u << 14) { x -= 5u << 14; y |= 1u << 14; } goto L6; }
                else
                { y = 1u << 17; x -= 1u << 18; if (x >= 5u << 16) { x -= 5u << 16; y |= 1u << 16; } goto L7; }
            }
            else
            {
                if (x < 1u << 22)
                { y = 1u << 19; x -= 1u << 20; if (x >= 5u << 18) { x -= 5u << 18; y |= 1u << 18; } goto L8; }
                else
                { y = 1u << 21; x -= 1u << 22; if (x >= 5u << 20) { x -= 5u << 20; y |= 1u << 20; } goto L9; }
            }
        }
        else
        {
            if (x < 1u << 28)
            {
                if (x < 1u << 26)
                { y = 1u << 23; x -= 1u << 24; if (x >= 5u << 22) { x -= 5u << 22; y |= 1u << 22; } goto La; }
                else
                { y = 1u << 25; x -= 1u << 26; if (x >= 5u << 24) { x -= 5u << 24; y |= 1u << 24; } goto Lb; }
            }
            else
            {
                if (x < 1u << 30)
                { y = 1u << 27; x -= 1u << 28; if (x >= 5u << 26) { x -= 5u << 26; y |= 1u << 26; } goto Lc; }
                else
                { y = 1u << 29; x -= 1u << 30; if (x >= 5u << 28) { x -= 5u << 28; y |= 1u << 28; } }
            }
        }
    }
    z = y | 1u << 26; y /= 2; if (x >= z) { x -= z; y |= 1u << 26; }
Lc: z = y | 1u << 24; y /= 2; if (x >= z) { x -= z; y |= 1u << 24; }
Lb: z = y | 1u << 22; y /= 2; if (x >= z) { x -= z; y |= 1u << 22; }
La: z = y | 1u << 20; y /= 2; if (x >= z) { x -= z; y |= 1u << 20; }
L9: z = y | 1u << 18; y /= 2; if (x >= z) { x -= z; y |= 1u << 18; }
L8: z = y | 1u << 16; y /= 2; if (x >= z) { x -= z; y |= 1u << 16; }
L7: z = y | 1u << 14; y /= 2; if (x >= z) { x -= z; y |= 1u << 14; }
L6: z = y | 1u << 12; y /= 2; if (x >= z) { x -= z; y |= 1u << 12; }
L5: z = y | 1u << 10; y /= 2; if (x >= z) { x -= z; y |= 1u << 10; }
L4: z = y | 1u << 08; y /= 2; if (x >= z) { x -= z; y |= 1u << 08; }
L3: z = y | 1u << 06; y /= 2; if (x >= z) { x -= z; y |= 1u << 06; }
L2: z = y | 1u << 04; y /= 2; if (x >= z) { x -= z; y |= 1u << 04; }
L1: z = y | 1u << 02; y /= 2; if (x >= z) { x -= z; y |= 1u << 02; }
L0: return x > y ? y / 2 | 1u : y / 2;
}

Ответ 13

использовать двоичный поиск

public class FindSqrt {

    public static void main(String[] strings) {

        int num = 10000;
        System.out.println(sqrt(num, 0, num));
    }

    private static int sqrt(int num, int min, int max) {
        int middle = (min + max) / 2;
        int x = middle * middle;
        if (x == num) {
            return middle;
        } else if (x < num) {
            return sqrt(num, middle, max);
        } else {
            return sqrt(num, min, middle);
        }
    }
}

Ответ 14

В общем случае квадратный корень из целого числа (например, 2) может быть только аппроксимирован (не из-за проблем с арифметикой с плавающей запятой, а потому, что они являются иррациональными числами, которые невозможно точно рассчитать).

Конечно, некоторые приближения лучше других. Я имею в виду, конечно, что значение 1.732 является лучшим приближением к квадратному корню из 3, чем 1,7

Метод, используемый кодом на той ссылке, которую вы дали, работает, беря в первом приближении и используя его для вычисления лучшего приближения.

Это называется Newton Method, и вы можете повторить расчет с каждым новым приближением, пока он не станет достаточно точным для вас.

Фактически существует must, чтобы решить, когда остановить повторение или он будет работать вечно.

Обычно вы останавливаетесь, когда разница между приближениями меньше значения, которое вы решите.

EDIT: я не думаю, что может быть более простая реализация, чем те, которые вы уже нашли.

Ответ 15

Обратное, как говорится в названии, но иногда "достаточно близко", "достаточно близко"; интересное чтение в любом случае.

Происхождение Quake3 Fast InvSqrt()

Ответ 16

// A Java program to find floor(sqrt(x)
public class Test
 {
   public static int floorSqrt(int x)
    {
    // Base Cases
    if (x == 0 || x == 1)
        return x;

    // Do Binary Search for floor(sqrt(x))
    int start = 1, end = x, ans=0;
    while (start <= end)
    {
        int mid = (start + end) / 2;

        // If x is a perfect square
        if (mid*mid == x)
            return mid;

        // Since we need floor, we update answer when mid*mid is
        // smaller than x, and move closer to sqrt(x)
        if (mid*mid < x)
        {
            start = mid + 1;
            ans = mid;
        }
        else   // If mid*mid is greater than x
            end = mid - 1;
    }
    return ans;
}

// Driver Method
public static void main(String args[])
{
    int x = 11;
    System.out.println(floorSqrt(x));
 }
}

вывод: 3 (этаж)

Let  's' be the answer.  We know that 0 <=  s <= x.

 Consider any random number r. 

If r*r <= x, s >= r

If r*r > x, s < r. 

Алгоритм:

  • Начните с "start" = 0, end = 'x', выполните следующие действия, пока "start" меньше или равно "концу".

  • a) Вычислить "середина" как (начало + конец)/2

  • b) сравните середину с серединой x.

  • c) Если x равно середине * mid, вернитесь в середине.
  • d) Если x больше, выполните двоичный поиск между серединой + 1 и концом. В этом случае мы также обновляем ans (обратите внимание, что нам нужен пол).
  • e) Если x меньше, выполните двоичный поиск между началом и средой-1

Сложность времени для решения выше: O (√ n).

Ответ 17

Простое решение, которое может обрабатывать квадратный корень и произвольную точность с использованием двоичного поиска

закодирован в рубине

include Math

def sqroot_precision num, precision
  upper   = num
  lower   = 0
  middle  = (upper + lower)/2.0

  while true do
    diff = middle**2 - num

    return middle if diff.abs <= precision

    if diff > 0
      upper = middle
    else diff < 0
      lower = middle
    end

    middle = (upper + lower)/2.0
  end 
end

puts sqroot_precision 232.3, 0.0000000001

Ответ 18

Скажем, мы пытаемся найти квадратный корень из 2, и у вас есть оценка 1.5. Будем говорить, что a = 2 и x = 1,5. Чтобы вычислить лучшую оценку, мы разделим a на x. Это дает новое значение y = 1.333333. Однако мы не можем просто считать это нашей следующей оценкой (почему бы и нет?). Нам нужно усреднить его с предыдущей оценкой. Итак, следующая оценка xx будет (x + y)/2 или 1.416666.

Double squareRoot(Double a, Double epsilon) {
    Double x = 0d;
    Double y = a;
    Double xx = 0d;

    // Make sure both x and y != 0.
    while ((x != 0d || y != 0d) && y - x > epsilon) {
        xx = (x + y) / 2;

        if (xx * xx >= a) {
            y = xx;
        } else {
            x = xx;
        }
    }

    return xx;
}

Эпсилон определяет, насколько точным должно быть приближение. Функция должна возвращать первое приближение x, которое оно получает, что удовлетворяет abs (x * x - a) epsilon, где abs (x) - абсолютное значение x.

square_root(2, 1e-6)
Output: 1.4142141342163086

Ответ 19

Ну, есть уже немало ответов, но здесь идет мой. Это самый простой фрагмент кода (для меня), вот algorithm для этого.

И код в python 2.7:

from __future__ import division 
val = 81
x = 10
def sqr(data,x):
    temp = x - ( (x**2 - data)/(2*x))
    if temp == x:
        print temp
        return
    else:
        x = temp
        return sqr(data,x)
    #x =temp 
    #sqr(data,x)
sqr(val,x)

Ответ 20

Чтобы вычислить квадратный корень из числа с помощью встроенной функции

# include"iostream.h"
# include"conio.h"
# include"math.h"
void main()
{
clrscr();
float x;
cout<<"Enter the Number";
cin>>x;

 float squreroot(float);  
 float z=squareroot(x);
 cout<<z;


float squareroot(int x)
    {


 float s;
 s = pow(x,.5)  
 return(s);
 }