Wie kann ich die Quadratwurzel von Float
in C#
, ähnlich Core.Sqrt
in XNA berechnen?So berechnen Sie die Quadratwurzel eines Float in C#
Antwort
Berechnen Sie es für double
und dann zurück in float. Kann ein bisschen langsam sein, sollte aber funktionieren.
(float)Math.Sqrt(inputFloat)
wont es lose Präzision? – Chris
Ich habe immer gehofft, dass irgendwie .Net dies optimieren würde, um ein All-Float (alle 32-Bit) Betrieb hinter den Kulissen zu sein. Weiß jemand, ob dies optimiert wird? – Detmar
@Chris, die Genauigkeit wird die gleiche wie die Eingabe sein. Die Berechnung erfolgt mit Doppelpunkten. –
Hass, dies zu sagen, aber 0x5f3759df scheint 3x solange Math.Sqrt zu nehmen. Ich habe gerade ein paar Tests mit Timern gemacht. Math.Sqrt in einer For-Schleife Zugriff auf vorberechnete Arrays ergab ca. 80ms. 0x5f3759df unter den gleichen Bedingungen ergab 180 + ms
Der Test wurde mehrmals mit dem Release-Modus Optimierungen durchgeführt.
Quelle unter:
/*
================
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();
}
}
Um ehrlich zu sein, das scheint ziemlich unorthodox, aber trotzdem interessant! – Tara
http://stackoverflow.com/questions/268853/is-it-possible-to-write-quakes-fast-invsqrt-function-in-c-? –
private double operand1;
private void squareRoot_Click(object sender, EventArgs e)
{
operand1 = Math.Sqrt(operand1);
this.textBox1.Text = operand1.ToString();
}
Willkommen bei Stack Overflow! Während diese Antwort wahrscheinlich richtig und nützlich ist, ist es vorzuziehen, wenn Sie [http://meta.stackexchange.com/q/114762/159034] erklären, wie es hilft, das Problem zu lösen. Dies wird besonders nützlich in der Zukunft, wenn es eine (möglicherweise nicht zusammenhängende) Änderung gibt, die dazu führt, dass es nicht mehr funktioniert und die Benutzer verstehen müssen, wie es einmal funktioniert hat. –
Verwendung mächtige Magie - [0x5f3759df] (http://www.codemaestro.com/reviews/9) – jball
Das Magie ist die inverse Quadratwurzel. Aber ähnliche Magie existiert für sqrt. Und das verliert Präzision. – CodesInChaos
@CodeInChaos - das zweite Codebeispiel im Artikel hat eine Implementierung für sqrt: * "Beachten Sie, dass der einzige wirkliche Unterschied im Rückgabewert liegt - anstatt y zurückzugeben, geben Sie die Zahl * y als Quadratwurzel an" * – jball