Sul valore di System.Double.Epsilon, la documentazione dice solo che "The value of this constant is 4.94065645841247e-324". Vediamo se, utilizzando la tabella della rappresentazione su 64 bit di un double, riusciamo a trovare il valore esatto di questa costante.
Se 0<E<2047 allora -1023<E-1023<1024. Siamo quindi nel caso:
Pow(-1,S)*Pow(2,-1022)*(0.F)
Ma siccome Epsilon>0 abbiamo S=0 e:
Epsilon = Pow(2,-1022)*(0.F)
F è il numero minino, positivo e minore di 1, che si rappresenta in modo binario su 52 bit, quindi:
F = Pow(2,-52)
e Epsilon = Pow(2,-1022)*Pow(2,-52)
cioè Epsilon = Pow(2,-1074).
Valore confermato da SLAR dove, alla pagina 157, si può leggere: "A System.Double can represent [...] the finite set of non-zero values of the form s*m*Pow(2,e), where s is 1 or -1, and 0<m<Pow(2,53) and -1075<=e<=970.". Nel caso di Epsilon:
s=1, m=1, e=-1074.
Se vi chiedete come mai non -1075, vi faccio notare che m>0 e quindi Pow(2,-1075)=0. :-)
Tutto, facilmente verificabile:
Console.WriteLine(Math.Pow(2, -1074) == Double.Epsilon);
Console.WriteLine(Math.Pow(2, -1075));
Aggiornamento: Stavo rileggendo il post e mi sono fermato su "non-zero values ". La mia interpretazione è:
un double sì, può rappresentare il valore non-zero di Pow(2,-1075), ma lo rappresenta come zero . :-)
Voi cosa ne dite?