Feedback

C# - Exponent und Mantisse von Double ermitteln

Veröffentlicht von am 24.08.2013
(0 Bewertungen)
Ein Double-Wert wird intern in 2 Teilen gespeichert. Die Teile nennen sich Mantisse und Exponent. Die Mantisse enthält die einzelnen 'Ziffern'. Der Exponent gibt an, um wie viele Stellen die Werte verschoben werden sollen.
Dieses Snippet gibt diese beiden Teile eines Double's zurück.

Wenn man die ermittelten Werte manuell überprüft, muss man beachten das die Ziffern im Binärsystem verschoben werden müssen. Getestet habe ich den Code über einen Unittest:

#region Test_Int64_GetSegments

[TestMethod]
public void Test_Int64_GetSegments()
{
double[] doubles = new double[] { 0, 96, 10, 10000000, 1111111111, 1.1, -3, -33,
-333, -3333, 3333, 33333333, -33333333333, 98765432109876543210987654321098D,
-98765432109876543210987654321098D, 0.00000000001, -0.00000000001,double.MaxValue, double.MinValue };
foreach (var d in doubles)
Check_Int64_GetSegments(d);//, 0, null);
}

#endregion

void Check_Int64_GetSegments(double d)
{
long m = 0;
int e = 0;
d.GetSegments(out m, out e);

Assert.AreEqual(m * Math.Pow(2, e), d, Math.Abs(d / 13/*13 Stellen*/));
}


Hinweis: Die Methode ist als Erweiterung für den Typ Double implementiert.
/// <summary>
/// Gibt die Mantisse sowie den Exponenten des Double-Wertes zurück.
/// </summary>
/// <param name="value">Der Wert, deren Mantisse und Exponent ermittelt werden sollen.</param>
/// <param name="mantissa">Die Mantisse von <paramref name="value"/>.</param>
/// <param name="exponent">Der Exponent von <paramref name="value"/>.</param>
public static void GetSegments(this double value, out long mantissa, out int exponent)
{
	long bits = BitConverter.DoubleToInt64Bits(value); // Einzelne Bits ermitteln //?  Siehe ggf.: http://dotnet-snippets.de/snippet/bits-zwischen-double-und-long-int64-konvertieren/2759
	bool negative = (bits < 0);
	exponent = (int)((bits >> 52) & 0x7ffL);
	mantissa = bits & 0xfffffffffffffL;

	if (exponent == 0)
		exponent++;
	else
		mantissa = mantissa | (1L << 52);

	exponent -= 1075; // 1023 (= 2 ^ 10 - 1) + 52

	if (mantissa == 0)
		return;

	// Normalisierung
	while ((mantissa & 1) == 0) // Solange Mantisse gerade ist
	{    
		mantissa >>= 1;
		exponent++;
	}
	if (negative) // Mantisse negativ machen, wenn d auch negativ ist
		mantissa = -mantissa;
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!