Поиск квадратного корня без использования функции sqrt?
я выяснял алгоритм поиска квадратного корня без использования функции sqrt, а затем попытался ввести его в Программирование. Я заканчиваю с этим рабочим кодом на C++
#include <iostream>
using namespace std;
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0; /* ek edited this line */
int nCount = 50;
while(nCount != 0)
{
temp=(lower_bound+upper_bound)/2;
if(temp*temp==num)
{
return temp;
}
else if(temp*temp > num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
nCount--;
}
return temp;
}
int main()
{
double num;
cout<<"Enter the numbern";
cin>>num;
if(num < 0)
{
cout<<"Error: Negative number!";
return 0;
}
cout<<"Square roots are: +"<<sqrtnum(num) and <<" and -"<<sqrtnum(num);
return 0;
}
теперь проблема заключается в инициализации числа итераций nCount в декларационе (здесь это 50). Например, чтобы узнать квадратный корень из 36, требуется 22 итерации, поэтому нет проблем, тогда как поиск квадратного корня из 15625 занимает более 50 итераций, поэтому он вернет значение temp после 50 итераций. Пожалуйста, дайте решение для этого.
9 ответов
существует лучший алгоритм, который требует не более 6 итераций для достижения максимальной точности для двойных чисел:
#include <math.h>
double sqrt(double x) {
if (x <= 0)
return 0; // if negative number throw an exception?
int exp = 0;
x = frexp(x, &exp); // extract binary exponent from x
if (exp & 1) { // we want exponent to be even
exp--;
x *= 2;
}
double y = (1+x)/2; // first approximation
double z = 0;
while (y != z) { // yes, we CAN compare doubles here!
z = y;
y = (y + x/y) / 2;
}
return ldexp(y, exp/2); // multiply answer by 2^(exp/2)
}
алгоритм начинается с 1 в первом приближении для значения квадратного корня.
Затем на каждом шаге он улучшает следующее приближение, принимая среднее между текущим значением y
и x/y
. Если y
= sqrt(x)
, это будет то же самое. Если y
>sqrt(x)
, потом x/y
sqrt(x) примерно на ту же сумму. Другими словами, он будет сходиться очень быстрый.
обновление: чтобы ускорить сходимость на очень больших или очень малых числах, изменено sqrt()
функция для извлечения двоичного показателя и вычисления квадратного корня из числа в
удалить nCount
всего (так как есть некоторые корни, для которых этот алгоритм займет много итераций).
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0;
while(fabs(num - (temp * temp)) > SOME_SMALL_VALUE)
{
temp = (lower_bound+upper_bound)/2;
if (temp*temp >= num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
}
return temp;
}
Если вам нужно найти квадратный корень без использования sqrt()
используйте root=pow(x,0.5)
.
где x-значение, квадратный корень которого вам нужно найти.
почему бы не попробовать использовать Вавилонский метод для поиска квадратного корня.
вот мой код:
double sqrt(double number)
{
double error = 0.00001; //define the precision of your result
double s = number;
while ((s-number/s)>error) //loop until precision satisfied
{
s = (s+number/s)/2;
}
return s;
}
удачи!
Как я нашел этот вопрос и много ответов, но у меня есть ответ, который прост и отлично работает..
#define EPSILON 0.0000001 // least minimum value for comparison
double SquareRoot(double _val) {
double low = 0;
double high = _val;
double mid = 0;
while (high - low > EPSILON) {
mid = low + (high - low) / 2; // finding mid value
if (mid*mid > _val) {
high = mid;
} else {
low = mid;
}
}
return mid;
}
Я надеюсь, что это будет полезно для будущих пользователей.
//long division method.
#include<iostream>
using namespace std;
int main() {
int n, i = 1, divisor, dividend, j = 1, digit;
cin >> n;
while (i * i < n) {
i = i + 1;
}
i = i - 1;
cout << i << '.';
divisor = 2 * i;
dividend = n - (i * i );
while( j <= 5) {
dividend = dividend * 100;
digit = 0;
while ((divisor * 10 + digit) * digit < dividend) {
digit = digit + 1;
}
digit = digit - 1;
cout << digit;
dividend = dividend - ((divisor * 10 + digit) * digit);
divisor = divisor * 10 + 2*digit;
j = j + 1;
}
cout << endl;
return 0;
}
вот очень простой, но небезопасных подход, чтобы найти квадратный корень из числа.
Небезопасно, потому что он работает только по натуральным числам, где вы знаете, что база соответственно экспонента являются натуральными числами. Я должен был использовать его для задачи, где мне не разрешалось использовать #включить
потенция = база ^ показатель
// FUNCTION: square-root
int sqrt(int x)
{
int quotient = 0;
int i = 0;
bool resultfound = false;
while (resultfound == false) {
if (i*i == x) {
quotient = i;
resultfound = true;
}
i++;
}
return quotient;
}
вот очень удивительный код, чтобы найти sqrt и даже быстрее, чем оригинальная функция sqrt.
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f375a86 - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x=1/x;
return x;
}
после просмотра предыдущих ответов, я надеюсь, что это поможет решить любые двусмысленности. В случае, если сходства в предыдущих решениях и моем решении иллюзорны, или этот метод решения для корней неясен, я также сделал график, который можно найти здесь.
это рабочая корневая функция, способная решать для любого nth-root
(по умолчанию квадратный корень для этого вопрос)
#include <cmath>
// for "pow" function
double sqrt(double A, double root = 2) {
const double e = 2.71828182846;
return pow(e,(pow(10.0,9.0)/root)*(1.0-(pow(A,-pow(10.0,-9.0)))));
}
объяснение:
это работает через ряд Тейлора, логарифмические свойства, и немного алгебры.
возьмите, например:
log A = N
x
Примечание: для квадратного корня N = 2; для любого другого корня вам нужно только изменить одну переменную, N.
1) измените базу, преобразуйте базовую функцию журнала " x " в естественную лог,
log A => ln(A)/ln(x) = N
x
2) переставить, чтобы изолировать ln (x), и в конечном итоге просто "x",
ln(A)/N = ln(x)
3) Установите обе стороны в качестве показателей 'e',
e^(ln(A)/N) = e^(ln(x)) >~{ e^ln(x) == x }~> e^(ln(A)/N) = x
4) серия Тейлора представляет " ln " как бесконечный ряд,
ln(x) = (k=1)Sigma: (1/k)(-1^(k+1))(k-1)^n
<~~~ expanded ~~~>
[(x-1)] - [(1/2)(x-1)^2] + [(1/3)(x-1)^3] - [(1/4)(x-1)^4] + . . .
Примечание: продолжайте серию для увеличенной точности. Для краткости в моей функции используется 10^9, которая выражает сходимость рядов для естественного журнала С примерно 7 цифрами, или 10-миллионным местом, для точность,
ln(x) = 10^9(1-x^(-10^(-9)))
5) Теперь просто подключите это уравнение для естественного входа в упрощенное уравнение, полученное на Шаге 3.
e^[((10^9)/N)(1-A^(-10^-9)] = nth-root of (A)
6) эта реализация может показаться излишней; однако ее цель-продемонстрировать, как вы можете решить для корней, не догадываясь и не проверяя. Кроме того, это позволит вам заменить функцию pow из библиотеки cmath вашей собственной функцией pow:
double power(double base, double exponent) {
if (exponent == 0) return 1;
int wholeInt = (int)exponent;
double decimal = exponent - (double)wholeInt;
if (decimal) {
int powerInv = 1/decimal;
if (!wholeInt) return root(base,powerInv);
else return power(root(base,powerInv),wholeInt,true);
}
return power(base, exponent, true);
}
double power(double base, int exponent, bool flag) {
if (exponent < 0) return 1/power(base,-exponent,true);
if (exponent > 0) return base * power(base,exponent-1,true);
else return 1;
}
int root(int A, int root) {
return power(E,(1000000000000/root)*(1-(power(A,-0.000000000001))));
}