Da uno scambio di messaggi questi giorni sul Messenger con M.rkino e Gianluca, sono usciti fuori alcuni aspetti della System.Double, a prima vista strani. Per esempio, questo di seguito, presentato da Brian Grunkemeyer in SLAR (p. 156):
"You might wonder why this simple code would throw an OverflowException:
string s = Double.MaxValue.ToString();
double d = Convert.ToDouble(s);
The Convert.ToDouble() method throws an exception due to rounding errors. Note that the IEEE spec for doubles says that a double has about 15.7 decimal digits worth of precision, but to accurately represent that number you need to print out 17 digits to avoid rounding errors."
Lo standard a cui fa riferimento è lo "ANSI/IEEE 754-1985: IEEE Standard for Binary Floating-Point Arithmetic". In sostanza, la rappresentazione su 64 bit di un double D descritta dallo standard, identifica il primo bit (S) come il bit di segno, i prossimi 11 come i bit dell'esponente (E) e gli ultimi 52 come i bit della parte frazionaria (F). Il valore D del double risulta allora in base a questa tabella:
S |
E |
F |
D |
* |
2047 |
F>0 |
System.Double.NaN |
1 |
2047 |
0 |
System.Double.NegativeInfinity |
0 |
2047 |
0 |
System.Double.PositiveInfinity |
S |
0<E<2047 < TD>
| F |
Pow(-1,S)*Pow(2,E-1023)*(1.F) |
S |
0 |
F > 0 |
Pow(-1,S)*Pow(2,-1022)*(0.F) |
1 |
0 |
0 |
-0 |
0 |
0 |
0 |
0 |
| | | |