Escribir su propia función de raíz cuadrada
¿Cómo escribe su propia función para encontrar la raíz cuadrada más precisa de un entero?
Después de buscarlo en Google, encontré este (archivado desde su enlace original), pero primero, no lo conseguí completamente, y segundo, también es aproximado.
Asuma la raíz cuadrada como el entero más cercano (a la raíz real) o un flotador.
20 answers
El siguiente calcula floor (sqrt (N)) para N > 0:
x = 2^ceil(numbits(N)/2)
loop:
y = floor((x + floor(N/x))/2)
if y >= x
return x
x = y
Esta es una versión del método de Newton dado en Crandall & Pomerance, "Números primos: Una perspectiva Computacional". La razón por la que debe usar esta versión es que las personas que saben lo que están haciendo han demostrado que converge exactamente al piso de la raíz cuadrada, y es simple, por lo que la probabilidad de cometer un error de implementación es pequeña. También es rápido (aunque es posible construir un algoritmo aún más rápido -- pero hacerlo correctamente es mucho más complejo). Una búsqueda binaria correctamente implementada puede ser más rápida para N muy pequeña, pero allí también puede usar una tabla de búsqueda.
Para redondear al entero más cercano, simplemente calcule t = floor(sqrt(4N)) utilizando el algoritmo anterior. Si se establece el bit menos significativo de t, elija x = (t + 1)/2; de lo contrario, elija t / 2. Tenga en cuenta que esto redondea hacia arriba en un empate; también podría redondear hacia abajo (o redondear a par) mirando si el resto es distinto de cero (es decir, si t^2 = = 4N).
Tenga en cuenta que no necesita usar aritmética de coma flotante. Este algoritmo debería implementarse completamente usando enteros (en particular, las funciones floor () solo indican que se debe usar la división regular de enteros).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-23 16:09:23
Dependiendo de sus necesidades, se puede usar una estrategia simple de dividir y conquistar. No convergerá como rápido como algunos otros métodos, pero puede ser mucho más fácil de entender para un novato. Además, dado que es un algoritmo O(log n) (reduciendo a la mitad el espacio de búsqueda en cada iteración), el peor caso para un float de 32 bits será 32 iteraciones.
Digamos que quieres la raíz cuadrada de 62.104. Usted elige un valor a medio camino entre 0 y eso, y el cuadrado. Si el cuadrado es más alto que su número, necesitas concentrarte en números menores que el punto medio. Si es demasiado bajo, concéntrate en los más altos.
Con matemáticas reales, podrías seguir dividiendo el espacio de búsqueda en dos para siempre (si no tiene una raíz cuadrada racional). En realidad, las computadoras eventualmente se quedarán sin precisión y tendrás tu aproximación. El siguiente programa C ilustra el punto:
#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;
}
Aquí hay un par de carreras para que con suerte te hagas una idea de cómo funciona. Para 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
Para 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
Para 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-19 11:34:00
Un método simple (pero no muy rápido) para calcular la raíz cuadrada de 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;
Ejemplo: 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
Como puede ver, define un límite superior e inferior para la raíz cuadrada y estrecha el límite hasta que su tamaño sea aceptable.
Hay métodos más eficientes, pero este ilustra el proceso y es fácil de entender.
Solo tenga cuidado de establecer el Errormargin a 1 si usa enteros de lo contrario tiene un bucle sin fin.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-19 12:21:07
Permítanme señalar un método extremadamente interesante para calcular una raíz cuadrada inversa 1/sqrt(x) que es una leyenda en el mundo del diseño de juegos porque es increíblemente rápido. O espere, lea el siguiente post:
Http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root /
PD: Sé que solo quieres la raíz cuadrada, pero la elegancia de quake superó toda resistencia de mi parte:)
Por cierto, el artículo mencionado anteriormente también habla de la aburrida aproximación de Newton-Raphson en alguna parte.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-26 07:40:40
Por supuesto que es aproximado; así es como funcionan las matemáticas con números de coma flotante.
De todos modos, la forma estándar es con el método de Newton. Esto es casi lo mismo que usar la serie de Taylor, la otra forma que viene a la mente inmediatamente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-26 06:40:50
Calcular la raíz cuadrada con precisión arbitraria en 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()
Salida:
111.10805551354051124500443874307524148991137745969772997648567316178259031751676
True
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-16 00:23:38
Es una pregunta de entrevista común hecha por Facebook, etc. No creo que sea una buena idea usar el método de Newton en una entrevista. ¿Qué pasa si el entrevistador te pregunta el mecanismo del método de Newton cuando realmente no lo entiendes?
Proporcioné una solución basada en búsqueda binaria en Java que creo que todo el mundo puede entender.
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;
}
Puedes probar mi código aquí: leetcode: sqrt (x)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-28 06:35:14
Encontró un gran artículo sobre Raíces Cuadradas enteras.
Esta es una versión ligeramente mejorada que presenta allí:
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-24 12:26:00
Aquí hay una forma de obtener una raíz cuadrada usando trigonometría. No es el algoritmo más rápido, pero es preciso. El código está en 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-02 19:51:34
Hay un algoritmo que estudié en la escuela que se puede utilizar para calcular raíces cuadradas exactas (o de precisión arbitrariamente grande si la raíz es un número irracional). Es definitivamente más lento que los algoritmos de Newton, pero es exacto. Digamos que desea calcular la raíz cuadrada de 531.3025
Lo primero es dividir su número a partir del punto decimal en grupos de 2 dígitos:
{5}{31}.{30}{25}
Entonces:
1) Encontrar la raíz cuadrada más cercana para el primer grupo que es menor o igual a la raíz cuadrada real del primer grupo: sqrt ({5}) > = 2. Esta raíz cuadrada es el primer dígito de su respuesta final. Permite denotar los dígitos que ya hemos encontrado de nuestra raíz cuadrada final como B. Por lo que en el momento B = 2.
2) A continuación calcular la diferencia entre {5} y B^2: 5-4 = 1.
3) Para todos los siguientes grupos de 2 dígitos haga lo siguiente:
Multiplique el resto por 100, luego añádalo al segundo grupo: 100 + 31 = 131.
Encontrar X-siguiente dígito de la raíz, de modo que 131 >=((B * 20) + X) * X. X = 3. 43 * 3 = 129
4) Repita lo mismo para {30} y {25}. Así que tienes:
{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
Resultado Final = 23.05.
El algoritmo se ve complicado de esta manera, pero es mucho más simple si lo haces en papel usando la misma notación que usas para "división larga" que has estudiado en la escuela, excepto que no haces división, sino que calculas la raíz cuadrada.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-11 18:25:05
Lo primero que me viene a la mente es: este es un buen lugar para usar la búsqueda binaria (inspirado en este gran tutoriales.)
Para encontrar la raíz cuadrada de vaule
, estamos buscando el number
en (1..value)
donde el predictor
es verdad por primera vez. El predictor que estamos eligiendo es 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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-09 20:48:20
// Fastest way I found, an (extreme) C# unrolled version of:
// http://www.hackersdelight.org/hdcodetxt/isqrt.c.txt (isqrt4)
// It's quite a lot of code, basically a binary search (the "if" statements)
// followed by an unrolled loop (the labels).
// Most important: it's 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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-24 16:03:55
Use búsqueda binaria
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);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-14 13:25:18
En general, la raíz cuadrada de un entero (como 2, por ejemplo) puede solo ser aproximada (no por problemas con la aritmética de coma flotante, sino porque son números irracionales que no se pueden calcular exactamente).
Por supuesto, algunas aproximaciones son mejores que otras. Quiero decir, por supuesto, que el valor 1.732 es una mejor aproximación a la raíz cuadrada de 3, que 1.7
El método utilizado por el código en ese enlace que dio funciona tomando una primera aproximación y usándola para calcular una mejor aproximación.
Esto se llama Método de Newton, y puedes repetir el cálculo con cada nueva aproximación hasta que sea lo suficientemente preciso para ti.
De hecho, debe haber alguna manera de decidir cuándo detener la repetición o se ejecutará para siempre.
Normalmente te detendrías cuando la diferencia entre aproximaciones sea menor que un valor que tú decidas.
EDITAR: No creo que haya puede ser una implementación más simple que las dos que ya encontró.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-26 07:05:28
Lo inverso, como dice su nombre, pero a veces "lo suficientemente cerca" es "lo suficientemente cerca"; una lectura interesante de todos modos.
// 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));
}
}
Salida: 3 (piso)
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.
Algoritmo:
Comience con 'start' = 0, end = 'x', Haga lo siguiente mientras 'start' es menor o igual a 'end'.
A) Calcular ' mid ' como (inicio + fin)/2
-
B) compare mid * mid con x.
- c) Si x es igual a mid*mid, vuelva mid.
- d) Si x es mayor, haga una búsqueda binaria entre mid+1 y end. En este caso, también actualizamos ans (Tenga en cuenta que necesitamos piso).
- e) Si x es más pequeño, haga una búsqueda binaria entre inicio y mediados de-1
La complejidad temporal de la solución anterior es O (√ n).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-01 12:45:27
Una solución simple que puede tratar con raíz cuadrada flotante y precisión arbitraria usando búsqueda binaria
Codificado en ruby
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-27 06:42:52
Digamos que estamos tratando de encontrar la raíz cuadrada de 2, y tiene una estimación de 1,5. Diremos a = 2, y x = 1.5. Para calcular una mejor estimación, vamos a dividir a por x. Esto da un nuevo valor y = 1.333333. Sin embargo, no podemos simplemente tomar esto como nuestra próxima estimación (¿por qué no?). Tenemos que promediarlo con la estimación anterior. Así que nuestra próxima estimación, xx será (x + y) / 2, o 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;
}
Epsilon determina cuán precisa debe ser la aproximación. La función debe devolver la primera aproximación x obtiene que satisface abs (x*x - a)
square_root(2, 1e-6)
Output: 1.4142141342163086
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-10 00:24:02
Bueno, ya hay bastantes respuestas, pero aquí va la mía Es la pieza de código más simple ( para mí), aquí está el algoritmo para ello.
Y código en 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-11 15:34:17
Para calcular la raíz cuadrada de un número con ayuda de la función incorporada
# 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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-25 04:11:17