¿Cómo se implementa la función de raíz cuadrada?¿Cómo se implementa la función de raíz cuadrada?
Respuesta
En el hardware Intel, a menudo se implementa sobre las instrucciones de hardware SQRT. Algunas bibliotecas simplemente usan el resultado de inmediato, algunos pueden pasar por un par de rondas de optimización de Newton para hacerlo más preciso en los casos de esquina.
Fuente here.
Enunciado del problema: Dado x> 0, encuentre y tal que y^2 = x => y = x/y (este es el paso clave).
1) Adivina un valor g para y y pruébalo.
2) Calcula x/g.
3) Si x/g es lo suficientemente cerca de g, devuelve g. De lo contrario, intenta adivinar mejor.
double test(double x, double g) {
if closeEnough(x/g, g)
return g;
else
return test(x, betterGuess(x, g));
}
boolean closeEnough(double a, double b) {
return (Math.abs(a - b) < .001);
}
double betterGuess(double x, double g) {
return ((g + x/g)/2);
}
sqrt(2) | Guess g x/g | New guess, (g + x/g)/2
----------------|------------------------------|-------------------------------
test(2, 1) | 1 2/1 = 2 | (2 + 1)/2 = 1.5
test(2, 1.5) | 1.5 2/1.5 = 1.3333 | (1.3333 + 1.5)/2 = 1.4167
test(2, 1.4167) | 1.4167 2/1.4167 = 1.4118 | (1.4167 + 1.4118)/2 = 1.4142
test(2, 1.4142) | 1.4142 ... | ...
Gran ejemplo y explicación. –
Nice copy-paste. Agregue la fuente al menos http://www.cs.wustl.edu/~kjg/CS101_SP97/Notes/SquareRoot/sqrt.html – Hartok
Bueno, este código resuelve el problema, pero ¿hay algún algoritmo que haga una suposición aleatoria y luego trata de converger bastante rápido hacia la raíz cuadrada, por ejemplo, digamos que el número es 289 y queremos su raíz cuadrada, entonces lo que trato de decir es que no podemos implementar la aleatorización en el algoritmo y luego intentar actualizar nuestra conjetura usando alguna regla ? – AnkitSablok
Para el cálculo de la raíz cuadrada (sin utilizar la función incorporada math.sqrt):
SquareRootFunction.java
public class SquareRootFunction {
public double squareRoot(double value,int decimalPoints)
{
int firstPart=0;
/*calculating the integer part*/
while(square(firstPart)<value)
{
firstPart++;
}
if(square(firstPart)==value)
return firstPart;
firstPart--;
/*calculating the decimal values*/
double precisionVal=0.1;
double[] decimalValues=new double[decimalPoints];
double secondPart=0;
for(int i=0;i<decimalPoints;i++)
{
while(square(firstPart+secondPart+decimalValues[i])<value)
{
decimalValues[i]+=precisionVal;
}
if(square(firstPart+secondPart+decimalValues[i])==value)
{
return (firstPart+secondPart+decimalValues[i]);
}
decimalValues[i]-=precisionVal;
secondPart+=decimalValues[i];
precisionVal*=0.1;
}
return(firstPart+secondPart);
}
public double square(double val)
{
return val*val;
}
}
MainApp.java
import java.util.Scanner;
public class MainApp {
public static void main(String[] args) {
double number;
double result;
int decimalPoints;
Scanner in = new Scanner(System.in);
SquareRootFunction sqrt=new SquareRootFunction();
System.out.println("Enter the number\n");
number=in.nextFloat();
System.out.println("Enter the decimal points\n");
decimalPoints=in.nextInt();
result=sqrt.squareRoot(number,decimalPoints);
System.out.println("The square root value is "+ result);
in.close();
}
}
El cálculo de la parte entera parece ser lento si está calculando la raíz cuadrada de 1E36, por ejemplo. De hecho, probablemente desborde su tipo 'int', ¿no es así ?, antes de alcanzar el valor correcto. No estoy seguro de qué tan bien funcionará el algoritmo en su conjunto para encontrar la raíz cuadrada de 1E-36, tampoco. Puedes ajustar los exponentes, pero el rango suele ser de ± 300 o más, y no creo que tu código funcione bien para la mayoría de ese rango. –
aplicación simple usando Binary Search con C++
double root(double n){
double lo = 0, hi = n, mid;
for(int i = 0 ; i < 1000 ; i++){
mid = (lo+hi)/2;
if(mid*mid == n) return mid;
if(mid*mid > n){
hi = mid;
}else{
lo = mid;
}
}
return mid;
}
Tenga en cuenta que while
bucle es más común con la búsqueda binaria, pero personalmente prefiero utilizar for
cuando se trata de números decimales, se ahorra algunos casos especiales de manipulación y obtiene resultado bastante preciso de pequeños bucles como el 1000
o incluso el 500
(Ambos darán el mismo resultado para casi todos los números pero solo para estar seguros)
Esto es más lento para converger que el método de Newton-Raphson. Agrega 1 bit de precisión por iteración, mientras que N-R duplica el número de bits de precisión. Entonces, si no te importa 'lento', esto funciona. –
¿Puedo preguntar cómo agrega esto solo 1 bit por iteración? mientras que el método de Newton lo duplica? – Argento
Tu código reduce a la mitad el intervalo que se busca en cada iteración, que básicamente equivale a agregar 1 bit. Es una aproximación aproximada, pero cuente las iteraciones y vea.N-R usa cálculo y hace un mejor trabajo al predecir el resultado. Después de obtener algunos bits de precisión en la raíz cuadrada, converge muy rápidamente. Ver Wikipedia [Método de Newton - Ejemplo - Square Root] (https://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number) - o SO en [Escribir su propia función de raíz cuadrada] (http://stackoverflow.com/questions/1623375) o use su buscador preferido. –
El FDLIBM (Libremente Distribuible LIBM) tiene una versión documentada muy bonita de sqrt. e_sqrt.c.
Tiene una versión que utiliza la aritmética de enteros y una fórmula de recurrencia que modifica un bit a la vez.
Otro método utiliza el método de Newton. Se inicia con un poco de magia negro y una tabla de búsqueda para obtener los primeros 8 bits y luego se aplica la fórmula de recurrencia
y_{i+1} = 1/2 * (y_i + x/y_i)
donde x es el número que empezamos. Este es el Babylonian method del método de Heron. Se remonta a Hero of Alexandra en el primer DC centuary.
Hay otro método llamado Fast inverse square root o reciproot. que usa algún "pirateo de nivel de bit de coma flotante malvado" para encontrar el valor de 1/sqrt (x). i = 0x5f3759df - (i >> 1);
Explota la representación binaria de un flotante utilizando la mantis y el exponente. Si nuestro número x es (1 + m) * 2^e, donde m es la mantisa y e el exponente y el resultado y = 1/sqrt (x) = (1 + n) * 2^f.Tomando registros
lg(y) = - 1/2 lg(x)
f + lg(1+n) = -1/2 e - 1/2 lg(1+m)
Así que vemos que la parte exponente del resultado es -1/2 el exponente del número. La magia negra básicamente realiza un desplazamiento en modo bit sobre el exponente y usa una aproximación lineal en la mantisa.
Una vez que tenga una buena primera aproximación, puede usar los métodos de Newton para obtener un mejor resultado y finalmente un poco de nivel de trabajo para arreglar el último dígito.
sqrt(); función Detrás de las escenas.
Siempre comprueba los puntos medios en un gráfico. Ejemplo: sqrt (16) = 4; sqrt (4) = 2;
Ahora, si da alguna entrada dentro de 16 o 4 como sqrt (10) ==?
Encuentra el punto medio de 2 y 4 i.e = x, luego nuevamente encuentra el punto medio de xy 4 (Excluye el límite inferior en esta entrada). Repite este paso una y otra vez hasta que obtiene la respuesta perfecta, es decir, sqrt (10) == 3.16227766017. Se encuentra b/w 2 y 4.Toda esta función incorporada se crea utilizando cálculo, diferenciación e integración.
long long int floorSqrt(long long int x)
{
long long r = 0;
while((long)(1<<r)*(long)(1<<r) <= x){
r++;
}
r--;
long long b = r -1;
long long ans = 1 << r;
while(b >= 0){
if(((long)(ans|1<<b)*(long)(ans|1<<b))<=x){
ans |= (1<<b);
}
b--;
}
return ans;
}
- 1. ¿Metafunción de raíz cuadrada?
- 2. Cómo calcular la raíz cuadrada en python?
- 3. ¿Implementación de hardware de raíz cuadrada?
- 4. Cómo calcular la raíz cuadrada de un flotador en C#
- 5. Raíz cuadrada para Bigint en F #
- 6. raíz cuadrada de seguimiento del valor móvil
- 7. Take raíz cuadrada positiva en Mathematica
- 8. ¿Cómo puedo mejorar este método de raíz cuadrada?
- 9. ¿Dónde puedo encontrar el código fuente para la función de raíz cuadrada de Java?
- 10. Función Inside random() - ¿Cómo se implementa?
- 11. Raíz cuadrada inversa inusual de John Carmack (Quake III)
- 12. HTML, CSS: barra superior a juego símbolo de raíz cuadrada
- 13. ¿Cómo se implementa la función de JVM persistentes en cake?
- 14. ¿Cómo calculo la raíz cuadrada de un número sin usar builtins?
- 15. Función que implementa la interfaz
- 16. ¿Cómo se implementa __RTC_CheckEsp?
- 17. Aproximando la raíz cuadrada de la suma de dos cuadrados en un microcontrolador
- 18. ¿Cómo se implementa la propiedad de dependencia?
- 19. ¿Cómo se implementa la virtualización de aplicaciones?
- 20. ¿Cómo se implementa BigDecimal?
- 21. ¿cómo se implementa sarcmark?
- 22. ¿Cómo se implementa set()?
- 23. ¿Cómo se implementa HttpSession?
- 24. ¿Cómo se implementa "const"?
- 25. ¿Cómo se implementa OpenID?
- 26. ¿Cómo se implementa Set.toString()?
- 27. ¿Hay alguna función opencv como "cvHoughCircles()" para la detección cuadrada?
- 28. Implementación de la función de cálculo de raíz
- 29. Encontrar la raíz cuadrada de un número dado usando operaciones bit a bit
- 30. ¿Cómo se implementa la autenticación en servicestack.net
¿Cómo se implementa? – fenomas
@Matt: agregue "... pero trate de adivinar un poco mejor esta vez", ¡y esa es en realidad una descripción precisa! –
Posible duplicado de [Escribir su propia función de raíz cuadrada] (http://stackoverflow.com/questions/1623375/writing-your-own-square-root-function) –