Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: samsaga2 en 18 de Abril de 2005, 06:12:33 PM

Título: Raiz Cuadrada
Publicado por: samsaga2 en 18 de Abril de 2005, 06:12:33 PM
 A ver si podeis echarme una mano. Estoy liado haciendo chorraditas via j2me y me encuentro que me hace falta la funcion para calcular una raiz cuadrada pero esta no viene con el API del j2me.

¿Sabeis algun algoritmo para calcular la raiz cuadrada de dos numeros enteros? Es para un juego asi que prima la velocidad sobre la exactitud.
Título: Raiz Cuadrada
Publicado por: gdl en 18 de Abril de 2005, 06:26:08 PM
 Cuando te refieres a calcular la raíz cuadrada de dos números... ¿es a dos números por separado o es el módulo de un vector de dos componentes?
Título: Raiz Cuadrada
Publicado por: samsaga2 en 18 de Abril de 2005, 07:09:51 PM
Cita de: "gdl"Cuando te refieres a calcular la raíz cuadrada de dos números... ¿es a dos números por separado o es el módulo de un vector de dos componentes?
Perdon, se me colo lo de los dos numeros  :rolleyes:. Necesito el calculo normal de la raiz cuadrada de un numero.
Título: Raiz Cuadrada
Publicado por: Pogacha en 18 de Abril de 2005, 07:14:38 PM
 Deseas calcular la distancia del vector ...

Aproximacion usada en el doom:

ax = abs(x);
ay = abs(y);

if(ax>ay) Distancia = ax + ay/2;
else Distancia = ay + ax/2;


En flotante tengo:

// Fast reciprocal square root
__inline float RSqrt( float number ) {
   long i;
   float x2, y;
   const float threehalfs = 1.5f;
   x2 = number * 0.5f;
   y  = number;
   i  = * (long *) &y;
   i  = 0x5f3759df - (i >> 1);
   y  = * (float *) &i;
   y  = y * (threehalfs - (x2 * y * y));
   return y;
}


Edit: reviendo el ultimo post ... necesitas raiz cuadrada ... la inversa no te sirve ?

Saludos
Título: Raiz Cuadrada
Publicado por: Pogacha en 18 de Abril de 2005, 07:20:49 PM
 Tambien piensa que puedes usar una tabla de precalculo ...
Pero aquí tienes una :

Citarlong sqrt(long r)
{
   long t,b,c=0;

   for (b=0x10000000;b!=0;b>>=2) {
      t = c + b;
      c >>= 1;
      if (t <= r) {
         r -= t;
         c += b;
      }
   }
   return c;
}
Título: Raiz Cuadrada
Publicado por: Pogacha en 18 de Abril de 2005, 07:26:59 PM
 Paper de la raiz cuadrada reciproca rapida

Ojo que a cualquiera que le pongas sqrt(-10) terminara en crash o blop.

Saludos
Título: Raiz Cuadrada
Publicado por: senior wapo en 18 de Abril de 2005, 07:28:56 PM
 Te pego esto de la vieja "Snippets Collection", os sonará a los que hallais crecido viendo Barrio Sésamo o la Cometa Blanca... (twist)
Está en C y es para enteros, pero con J2ME no creo que uses floats...


#include <string.h>
#include "snipmath.h"

#define BITSPERLONG 32

#define TOP2BITS(x) ((x & (3L << (BITSPERLONG-2))) >> (BITSPERLONG-2))


/* usqrt:
   ENTRY x: unsigned long
   EXIT  returns floor(sqrt(x) * pow(2, BITSPERLONG/2))

   Since the square root never uses more than half the bits
   of the input, we use the other half of the bits to contain
   extra bits of precision after the binary point.

   EXAMPLE
       suppose BITSPERLONG = 32
       then    usqrt(144) = 786432 = 12 * 65536
               usqrt(32) = 370727 = 5.66 * 65536

   NOTES
       (1) change BITSPERLONG to BITSPERLONG/2 if you do not want
           the answer scaled.  Indeed, if you want n bits of
           precision after the binary point, use BITSPERLONG/2+n.
           The code assumes that BITSPERLONG is even.
       (2) This is really better off being written in assembly.
           The line marked below is really a "arithmetic shift left"
           on the double-long value with r in the upper half
           and x in the lower half.  This operation is typically
           expressible in only one or two assembly instructions.
       (3) Unrolling this loop is probably not a bad idea.

   ALGORITHM
       The calculations are the base-two analogue of the square
       root algorithm we all learned in grammar school.  Since we're
       in base 2, there is only one nontrivial trial multiplier.

       Notice that absolutely no multiplications or divisions are performed.
       This means it'll be fast on a wide range of processors.
*/

void usqrt(unsigned long x, struct int_sqrt *q)
{
     unsigned long a = 0L;                   /* accumulator      */
     unsigned long r = 0L;                   /* remainder        */
     unsigned long e = 0L;                   /* trial product    */

     int i;

     for (i = 0; i < BITSPERLONG; i++)   /* NOTE 1 */
     {
           r = (r << 2) + TOP2BITS(x); x <<= 2; /* NOTE 2 */
           a <<= 1;
           e = (a << 1) + 1;
           if (r >= e)
           {
                 r -= e;
                 a++;
           }
     }
     memcpy(q, &a, sizeof(long));
}

#ifdef TEST

#include <stdio.h>
#include <stdlib.h>

main(void)
{
     int i;
     unsigned long l = 0x3fed0169L;
     struct int_sqrt q;

     for (i = 0; i < 101; ++i)
     {
           usqrt(i, &q);
           printf("sqrt(%3d) = %2d, remainder = %2d\n",
                 i, q.sqrt, q.frac);
     }
     usqrt(l, &q);
     printf("\nsqrt(%lX) = %X, remainder = %X\n", l, q.sqrt, q.frac);
     return 0;
}

#endif /* TEST */


La colección entera está en la web, AQUI (www.snippets.org seccion C)
Título: Raiz Cuadrada
Publicado por: Pogacha en 18 de Abril de 2005, 07:41:31 PM
 En punto fijo! si lo mismo ...

typedf int fixed16;

fixed16 sqrt(int r)
{
  long t,b,c=0;
  r<<=8;
  for (b=0x10000000;b!=0;b>>=2) {
     t = c + b;
     c >>= 1;
     if (t <= r) {
        r -= t;
        c += b;
     }
  }
  return c;
}


Edit:
CitarLa colección entera está en la web, AQUI (www.snippets.org seccion C)
Muy interesante
Título: Raiz Cuadrada
Publicado por: Warchief en 19 de Abril de 2005, 12:09:11 AM
 http://www.rart.com/j2me-presentation/html...P60ME_java.html ?

http://henson.newmail.ru/j2me/Float.htm ?
Título: Raiz Cuadrada
Publicado por: fiero en 19 de Abril de 2005, 12:25:52 AM
 La raiz cuadrada de un número entero, es el número de valores impares que puedes restarle. Por ejemplo:

raiz de 4: -1-3 = 2 números
raiz de 8: -1-3 = 2 numeros
raiz de 9: -1-3-5 = 3 números
raiz de 15: -1-3-5 = 3 números
raiz de 16: -1-3-5-7 = 4 números

un saludo
Título: Raiz Cuadrada
Publicado por: shephiroth en 19 de Abril de 2005, 03:24:32 AM
 Fiero, muy bueno eso  (ole)  (ole)  (ole)

Pasandolo a codigo seria algo como:

int sqrt(int a)
{
int c;
for(c=1;a>=c;a-=c,c+=2);
return c/2;
}
Título: Raiz Cuadrada
Publicado por: Pogacha en 19 de Abril de 2005, 04:15:15 PM
 
CitarFiero, muy bueno eso   

Pasandolo a codigo seria algo como:
CODE 

int sqrt(int a)
{
int c;
for(c=1;a>=c;a-=c,c+=2);
return c/2;
}

Si, en esto se basa el algoritmo que postee yo y el del senior wapo que es casi lo mismo, excepto que el del señor wapo tiene parte decimal y me parece mas integro, el algoritmo de shephiroth tiene el problema de que no aprovecha las propiedades de la potencia ... para calcular una raiz n demora raiz de n o sea la raiz de 65536 en 256 iteraciones, los algoritmos de arriba utilizan las propiedades de la potencia para realizar el calculo en tiempo fijo por radix o sea en un k * numero de bits, para nuestro caso 16 iteraciones sin importar el numero que sea.

Saludos
Título: Raiz Cuadrada
Publicado por: shephiroth en 19 de Abril de 2005, 05:17:08 PM
 Wenas

Vuestro codigo no termino de entenderlo, >>= y <<= que hacen??
Título: Raiz Cuadrada
Publicado por: Warchief en 19 de Abril de 2005, 06:17:02 PM
Cita de: "shephiroth"Wenas

Vuestro codigo no termino de entenderlo, >>= y <<= que hacen??
Son contracción de operador.

a += 1; // es lo mismo que a = a+1;

entonces

a >>= 1; // deberia ser lo mismo que a = a >> 1;

No los he usado nunca, huyo de la oscuridad, pero supongo que son eso.
Título: Raiz Cuadrada
Publicado por: Pogacha en 19 de Abril de 2005, 07:26:18 PM
 incluso :

a<<=1;  es igual aa*=2;
y mas interesante aun
a<<=n;  es igual aa*=pow(2,n);

a<<=0;  es igual aa*=pow(2,0); lo que esa*=1;  
a>>=n;  es igual aa<<=-n; lo que esa/=pow(a,n);

lo que me da que puedo multiplicar y dividir por potencias de 2 a gusto y placer ...

Saludos
Título: Raiz Cuadrada
Publicado por: ethernet en 20 de Abril de 2005, 08:05:07 PM
 este post  debería ir directamente al foro del cotd !!
Título: Raiz Cuadrada
Publicado por: shephiroth en 20 de Abril de 2005, 08:13:01 PM
 Muchas gracias pogacha, ya me quedaron claros los operadores  (ole)  (ole)

P.D: Por mi al COTW tambien xDD
Título: Raiz Cuadrada
Publicado por: Pogacha en 21 de Abril de 2005, 02:34:23 PM
 La verdad es que ninguno de esos codigos fue hecho por ninguno de nosotros, la raiz cuadrada entera data del 50 y la reciproca de la raiz flotante, que es mas nueva, menos...