Esto se inspiró en esta pregunta de Stack Overflow .
Actualmente está en espera como off-topic y downvoted, así que por si acaso se borra aquí está la captura de pantalla (para nosotros los menos mortales con menos de 10K rep en ese sitio):
El programa está tratando de enumerar todos los double
valores entre estos dos números:
0.009999999999999999999999999999
0.099999999999999999999999999999
El código de la captura de pantalla no lo hará realmente, pero dejemos eso de lado por ahora.
Para aquellos que no estén familiarizados con el sistema de tipos de C#, un doble es un número en coma flotante (que se utiliza para representar números reales) con los siguientes atributos:
El tipo de valor Double representa un número de 64 bits de doble precisión con valores que van de 1,79769313486232e308 negativo a 1,79769313486232e308 positivo, así como cero positivo o negativo, PositiveInfinity, NegativeInfinity y no un número (NaN). Está pensado para representar valores extremadamente grandes (como las distancias entre planetas o galaxias) o extremadamente pequeños (la masa molecular de una sustancia en kilogramos) y que a menudo son imprecisos (como la distancia de la Tierra a otro sistema solar). El tipo Double cumple la norma IEC 60559:1989 (IEEE 754) para la aritmética binaria de punto flotante.
Ahora, obviamente, hay un número infinito de números reales entre estos valores, pero sólo un número finito de números en coma flotante (ya que cualquier número en un ordenador real sólo puede tener, obviamente, un número finito de dígitos).
La otra cosa que hay que entender es Doble.Epsilon que es la siguiente constante:
El valor de la propiedad Epsilon refleja el menor valor positivo de Double que es significativo en operaciones numéricas o comparaciones cuando el valor de la instancia Double es cero...
Más concretamente, el formato de punto flotante consta de un signo, una mantisa o significante de 52 bits y un exponente de 11 bits. Como muestra el siguiente ejemplo, el cero tiene un exponente de -1022 y una mantisa de 0. Epsilon tiene un exponente de -1022 y una mantisa de 1. Esto significa que Epsilon es el menor valor positivo de Double mayor que cero y representa el menor valor posible y el menor incremento posible para un Double cuyo exponente es -1022.
Mi pregunta, entonces: ¿cuántos números dobles hay entre 0,0099999999999999999999 y 0,099999999999999999999999999999?
Si no me equivoco, creo que preguntar cuántos números hay entre 0,009999999999999999999999 y 0,0999999999999999999999999999 es exactamente lo mismo que preguntar cuántos números hay entre 0,0 y 0,09 (que además es bastante más cómodo de leer y trabajar).
Como experimento, he probado el siguiente programa para tener una mejor idea del tamaño del número (sin esperar que se complete la ejecución):
double num = 0.0;
long count = 0;
// Loop through all of the double numbers from 0.0 to 0.09
while (num <= 0.09)
{
// Add the smallest possible increment
num += Double.Epsilon;
// Keep count of how many there are
count++;
}
// Print the number at the end
Console.WriteLine(count);
Detuve el programa después de dejarlo correr por un tiempo; el número actual era 1.86324012918674E-314 y el conteo era 3,771,240,006.
Sospecho fuertemente que podrías hacer alguna forma de aritmética en los exponentes o posiblemente establecer esto como una permutación de algún tipo; ¿hay una ecuación que pueda describir este problema?