2015-10-23 3 views
0

Я делаю программу на C++ для вычисления квадратного корня числа. Эта программа не использует встроенную математику «sqrt». Существуют две переменные: одна для номера, которую вводит пользователь, а другая для квадратного корня из этого числа. Эта программа не работает очень хорошо, и я уверен, что есть лучший способ сделать это:Программа для вычисления квадратного корня C++

Вот мой полный код:

#include <iostream> 
using namespace std; 

int main(){ 
    int squareroot = 0; 
    int number; 

    cout << "enter a number sp that i can calculate its squareroot" << endl; 

    cin >> number; 

    while (squareroot * squareroot != number){ 

     squareroot+=0.1; 

} 
cout << "the square root is" << squareroot << endl; 
return 0; 
} 

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

Заранее спасибо.

+9

Это не проблема программирования, но проблема в математике. Существует несколько (эффективных и менее эффективных) алгоритмов. Сначала вы должны выбрать один и погрузиться в него, пока вы не поймете его подробно, а затем попытайтесь его реализовать. – CompuChip

+3

Для начала вам нужно знать, что неинициализированная локальная переменная (например, ваша переменная 'squarertoot') имеет * неопределенное значение *, и использование их приведет к * неопределенному поведению *. Во-вторых, вы объявляете 'squareroot' как переменную * integer *, вы не можете добавить значение с плавающей запятой и ожидать, что она будет работать нормально. –

+0

replace! = С < – secolive

ответ

2

Ниже объяснение дается для вычисления целочисленного квадратного корня:

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

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

  1. вы работаете с int вы хотите добавить 1 к squareroot не 0,1

  2. вы хотите, чтобы остановить свой расчет при squareroot * squareroot равно или больше, чем number. Подумайте о том, было ли это число 26, у вас нет целого числа, которое умножается на 26.

  3. в случае числа, равного 26, вы хотите вернуть 5 или 6? После вашего while цикла значение squareroot будет 6, так что вы можете повернуть его вспять до 5 (если squareroot * squareroot отличается от number)

Ниже Exemple:

#include <iostream> 
using namespace std; 

int main(){ 
    int squareroot = 0; 
    int number; 

    cout << "enter a number sp that i can calculate its squareroot" << endl; 

    cin >> number; 

    while (squareroot * squareroot < number){ 
     squareroot+=1; 
    } 

    if (squareroot * squareroot != number) --squareroot; 

    cout << "the square root is" << squareroot << endl; 
    return 0; 
} 

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

int mySqrt(int x) { 
    if (x==0) return 0; 
    int left = 1; 
    int right = x; 
    int res; 

    while (left <= right) { 
     int mid = left + ((right-left)/2); 
     if (mid<=x/mid){ 
      left = mid+1; 
      res=mid; 
     } 
     else { 
      right=mid-1; 
     } 
    } 

    return res; 
} 
+5

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

+1

Но результат не обязательно является целым числом. – user1095108

+0

@ user1095108 Вы правы, приведенное выше объяснение работает только для вычисления целочисленного квадратного корня –

1

Эта функция будет вычислять пол квадратного корня, если А не является идеальной функция square.This в основном использует бинарные search.Two вещи, которые вы знаете заранее, что квадратный корень из числа будет меньше или равно этому числу, и оно будет больше или равно 1. Таким образом, мы можем применить двоичный поиск в этом диапазоне. Ниже моя реализация. Сообщите мне, если вы ничего не понимаете в коде. Надеюсь, это поможет ,

int sqrt(int A) { 
    if(A<1)return 0; 
    if(A==1)return 1; 

    unsigned long long start,end,mid,i,val,lval; 
    start = 1; 
    end = A; 
    while(start<=end){ 
     mid = start+(end-start)/2; 
     val = mid*mid; 
     lval = (mid-1)*(mid-1); 

     if(val == A)return mid;  
     else if(A>lval && A<val) return mid-1; 
     else if(val > A)end = mid; 
     else if(val < A)start = mid+1; 
    } 
} 
+3

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

+0

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

1

Эта функция использует интервалы вложенных (непроверенные), и вы можете определить точность:

#include <math.h> 
#include <stdio.h> 

double mySqrt(double r) { 
    double l=0, m; 
    do { 
    m = (l+r)/2; 
    if (m*m<2) { 
     l = m; 
    } else { 
     r = m; 
    } 
    } 
    while(fabs(m*m-2) > 1e-10);  
    return m; 
} 

Посмотреть https://en.wikipedia.org/wiki/Nested_intervals

+5

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

1

Проблемы с кодом, является то, что он работает только тогда, когда квадратный корень числа равно N * 0,1, где N - целое число, а это означает, что если ответ будет 1.4142, а не 1.400000000, то точно ваш код не удастся. Есть лучшие способы, но они все сложнее и используют численный анализ для приближения ответа, самым простым из которых является метод Ньютона-Рафсона.

вы можете использовать функцию ниже, эта функция использует метод Newton-Raphson для поиска корня, если вам нужна дополнительная информация о методе Ньютона-Рафсона, отметьте this статью wikipedia. и если вам нужна более высокая точность - но худшая производительность - вы можете уменьшить «0.001» до вашего уподобления или увеличить его, если хотите более высокую производительность, но меньшую точность.

float mysqrt(float num) { 
    float x = 1; 

    while(abs(x*x - num) >= 0.001) 
     x = ((num/x) + x)/2; 

    return x; 

} 

, если вы не хотите импортировать math.h вы можете написать свой собственный abs():

float abs(float f) { 
    if(f < 0) 
     f = -1*f; 
    return f; 
} 
Смежные вопросы