Как написать собственную функцию извлечения кв. корня из целого числа?

Попробовал написать аналог функции sqrt(), но для целых чисел. Что можно сделать лучше, быстрее? Я просто начинающий, не хотелось бы "говнокодить" с самого начала изучения языка. Знаю, что register средой visual c++ не воспринимается, но судя по литературе, в других компайлерах скорость работы ускорить должно. Заранее спасибо за ответы.
int my_sqr(int number){
	register unsigned int temp = 0, x = 1;
	if (number < 0) number = -number;
	while (temp != x){
	temp = number / x;
	if (temp == x) return x;
	x++;
	}
};
  • Вопрос задан
  • 11946 просмотров
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Что можно сделать лучше, быстрее?

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

Например так:
int my_sqr(int number){
	register unsigned int temp, x;
	if (number < 0)
		number = -number;
	for (temp = 0, x = 1u << (sizeof(unsigned int) * 4 - 1); x; x >>= 1) {
		if ((temp | x) * (temp | x) <= number)
			temp |= x;
	}
	return temp;
}


Не проверять на равенство if (temp == x), потому что равенства может не быть, например для number = 6.
Убедиться, что функция всегда что-то возвращает. Так, например, при number = 6 ваша функция зацикливается или падает с делением на 0, а при number = 0 завершается с неопределённым значением.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
svd71
@svd71
ну наверное вспомнить математику и включить голову. логарифм от числа, деленный на логарифм основания дает нам степень:
a^b=c
b=ln(c)/ln(a)
a=exp(b * ln(c))

для квадратного корня b = 1/2
Ответ написан
AxisPod
@AxisPod
А использовать более оптимальные алгоритмы? Для целого числа очень подойдет разложение в ряд.
1 = 1^2
1 + 3 = 2^2
1 + 3 + 5 = 3^2
1 + 3 + 5 + 7 = 4^2
Замечаете?

Просто вычитаете все нечетные числа начиная с 1. Если остаток меньше следующего нечетного числа, то берете порядковый номер предыдущего нечетного числа. Но это подойдет, если числа не очень большие, хотя ваш алгоритм не лучше в этом отношении.

Ну и как обычно на тостере, поискать видимо лень, поэтому вопросов интересных нет, а вот такая вот фигня.

2 минуты поиска: algolist.manual.ru/maths/count_fast/intsqrt.php
Ответ написан
Комментировать
@dmitry2001
Существует такой алгоритм как бинпоиск
int sqrt (int v){
int L = 0, R = v;
int M = (L + R) /2;
while(R - L > 1){
    if(M * M <= v){
        L = M;
    }
    else{
        R = M;
    }
    M = (L + R)/2;
}
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы