In un'app ad alte prestazioni troviamo che la CPU può calcolare l'aritmetica lunga in modo significativamente più veloce rispetto a doppio. Tuttavia, nel nostro sistema è stato determinato che non abbiamo mai bisogno di più di 9 posizioni decimali di precisione. Quindi usiamo i long per tutte le aritmetiche in virgola mobile con una precisione di 9 punti capita.Converti mantissa ed esponente in doppio
Tuttavia, in alcune parti del sistema è più conveniente grazie alla leggibilità di lavorare con i doppi. Quindi dobbiamo convertire tra il valore lungo che assume 9 cifre decimali in doppio.
Troviamo semplicemente il prendere il lungo e dividendo per 10 alla potenza di 9 o moltiplicando per 1 diviso per 10 alla potenza di 9 fornisce rappresentazioni imprecise in un doppio.
Per risolvere questo abbiamo usato il Math.Round(value,9)
per dare i valori precisi.
Tuttavia, Math.Round()
è orribilmente lento per le prestazioni.
Quindi la nostra idea al momento è quella di convertire direttamente la mantissa e l'esponente nel formato binario di un doppio poiché - in questo modo, non ci sarà bisogno di arrotondare.
Abbiamo imparato online come esaminare i bit di un doppio per ottenere la mantissa e l'esponente, ma è confuso capire come invertire ciò per prendere una mantissa ed esponente e fabbricare un doppio usando i bit.
Qualche suggerimento?
[Test]
public unsafe void ChangeBitsInDouble()
{
var original = 1.0D;
long bits;
double* dptr = &original;
//bits = *(long*) dptr;
bits = BitConverter.DoubleToInt64Bits(original);
var negative = (bits < 0);
var exponent = (int) ((bits >> 52) & 0x7ffL);
var mantissa = bits & 0xfffffffffffffL;
if(exponent == 0)
{
exponent++;
}
else
{
mantissa = mantissa | (1L << 52);
}
exponent -= 1075;
if(mantissa == 0)
{
return;
}
while ((mantissa & 1) == 0)
{
mantissa >>= 1;
exponent++;
}
Console.WriteLine("Mantissa " + mantissa + ", exponent " + exponent);
}
Sei sicuro che il valore che hai è esattamente rappresentabile in un 'doppio? – Justin
forse questo sarà di aiuto, non voglio leggere tutto solo per aiutarti: P http://steve.hollasch.net/cgindex/coding/ieeefloat.html – MrFox