2010-12-03 13 views
7

¿Cómo puedo calcular la raíz cuadrada de Float en C#, similar a Core.Sqrt en XNA?Cómo calcular la raíz cuadrada de un flotador en C#

+1

Uso poderosa magia - [0x5f3759df] (http://www.codemaestro.com/reviews/9) – jball

+0

que la magia es el inverso de la raíz cuadrada. Pero existe una magia similar para sqrt. Y esto pierde precisión. – CodesInChaos

+0

@CodeInChaos - la segunda muestra de código en el artículo tiene una implementación para sqrt: * "Tenga en cuenta que la única diferencia real es en el valor de retorno - en lugar de devolver y, devolver el número * y como la raíz cuadrada" * – jball

Respuesta

15

Cómprelo para double y luego vuélvalo a flotar. Puede ser un poco lento, pero debería funcionar.

(float)Math.Sqrt(inputFloat) 
+0

¿no pierde la precisión? – Chris

+0

Siempre he esperado que de alguna manera .Net optimizara esto para que fuera una operación totalmente flotante (todo de 32 bits) detrás de escena. ¿Alguien sabe si esto se optimiza? – Detmar

+0

@Chris, la precisión será la misma que la de entrada. El cálculo se hace usando dobles. –

0
var result = Math.Sqrt((double)value); 
+1

flotante y doble calcular de manera diferente no? – Chris

+2

@Chris: el método Math.Sqrt toma un doble y devuelve un doble. Es por eso que elegí el parámetro como un doble. –

+0

Veo eso. Pero estoy hablando de carrozas. Gracias de todos modos – Chris

4

odio decir esto, pero parece 0x5f3759df tomar 3 veces el tiempo que Math.Sqrt. Acabo de hacer algunas pruebas con temporizadores. Math.Sqrt en un for-loop que accede a arreglos precalculados dio como resultado aproximadamente 80 ms. 0x5f3759df en las mismas circunstancias resultó en 180 + ms

La prueba se realizó varias veces utilizando las optimizaciones del modo de lanzamiento.

Fuente continuación:

/* 
    ================ 
    SquareRootFloat 
    ================ 
    */ 
    unsafe static void SquareRootFloat(ref float number, out float result) 
    { 
     long i; 
     float x, y; 
     const float f = 1.5F; 

     x = number * 0.5F; 
     y = number; 
     i = *(long*)&y; 
     i = 0x5f3759df - (i >> 1); 
     y = *(float*)&i; 
     y = y * (f - (x * y * y)); 
     y = y * (f - (x * y * y)); 
     result = number * y; 
    } 

    /* 
    ================ 
    SquareRootFloat 
    ================ 
    */ 
    unsafe static float SquareRootFloat(float number) 
    { 
     long i; 
     float x, y; 
     const float f = 1.5F; 

     x = number * 0.5F; 
     y = number; 
     i = *(long*)&y; 
     i = 0x5f3759df - (i >> 1); 
     y = *(float*)&i; 
     y = y * (f - (x * y * y)); 
     y = y * (f - (x * y * y)); 
     return number * y; 
    } 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     int Cycles = 10000000; 
     Random rnd = new Random(); 
     float[] Values = new float[Cycles]; 
     for (int i = 0; i < Cycles; i++) 
      Values[i] = (float)(rnd.NextDouble() * 10000.0); 

     TimeSpan SqrtTime; 

     float[] Results = new float[Cycles]; 

     DateTime Start = DateTime.Now; 

     for (int i = 0; i < Cycles; i++) 
     { 
      SquareRootFloat(ref Values[i], out Results[i]); 
      //Results[i] = (float)Math.Sqrt((float)Values[i]); 
      //Results[i] = SquareRootFloat(Values[i]); 
     } 

     DateTime End = DateTime.Now; 

     SqrtTime = End - Start; 

     Console.WriteLine("Sqrt was " + SqrtTime.TotalMilliseconds.ToString() + " long"); 
     Console.ReadKey(); 
    } 
} 
+3

Para ser sincero, esto parece bastante fuera de tema, ¡pero de todos modos es interesante! – Tara

+1

http://stackoverflow.com/questions/268853/is-it-possible-to-write-quakes-fast-invsqrt-function-in-c? –

-3
private double operand1; 

private void squareRoot_Click(object sender, EventArgs e) 
{ 
    operand1 = Math.Sqrt(operand1); 
    this.textBox1.Text = operand1.ToString(); 
} 
+2

¡Bienvenido a Stack Overflow! Si bien esta respuesta es probablemente correcta y útil, se prefiere si [incluye alguna explicación junto con ella] (http://meta.stackexchange.com/q/114762/159034) para explicar cómo ayuda a resolver el problema. Esto se vuelve especialmente útil en el futuro, si hay un cambio (posiblemente no relacionado) que hace que deje de funcionar y los usuarios deben comprender cómo funcionó. –

Cuestiones relacionadas