Aquí está la clave de su dilema: 10
es el producto de 2
y 5
. Puede representar cualquier número exactamente en la base 10 decimales que es k * 1/2 n * 1/5 m , donde k
, n
y m
son números enteros.
Alternativamente redactado: si el número n
en 1 / n contiene un factor que no es parte de los factores de la base, el número no podrá representarse exactamente en un número fijo de dígitos en el binario / decimal / cualquier expansión de ese número: tendrá una parte repetida. Por ejemplo 1/15 = 0.0666666666 .... porque 3 (15 = 3 * 5) no es un factor de 10.
Por lo tanto, cualquier cosa que pueda representarse exactamente en la base 2 (k * 1/2 n ) puede representarse exactamente en la base 10.
Más allá de eso, está la cuestión de cuántos dígitos / bits está utilizando para representar el número. Hay algunos números que pueden representarse exactamente en alguna base, pero se necesitan más de un número de dígitos / bits para hacerlo.
En binario, el número 1/10 que es convenientemente 0.1 en decimal no puede representarse como un número que puede representarse en un número fijo de bits en binario. En cambio, el número es 0.00011001100110011 ... 2 (con la parte 0011 repitiéndose para siempre).
Veamos el número 1 2 /1010 2 un poco más de cerca.
____
0.00011
+ ---------
1010 | 1.00000
0 0
-
1 0
0 0
----
1 00 --------- +
0 |
----- |
1 000 |
0 |
------ | repitiendo
1 0000 | bloquear
1010 |
------ |
1100 |
1010 |
---- |
100 ---- +
Este es exactamente el mismo tipo de cosas que obtienes cuando intentas hacer la división larga para 1/3.
1/10, cuando se factoriza es 1 / (2 1 * 5 1 ). Para la base 10 (o cualquier múltiplo de 10), este número termina y se conoce como un número regular . Una expansión decimal que se repite se conoce como decimal decimal , y los números que continúan para siempre sin repetirse son números irracionales.
La matemática detrás de esta ahonda en el pequeño teorema de Fermat ... y una vez que empieza a decir Fermat o teorema, se convierte en una cuestión Math.SE .
¿Hay números que no son representables en la base 10 pero que se pueden representar en la base 2?
La respuesta es no'.
Entonces, en este punto, todos deberíamos tener claro que cada expansión binaria de longitud fija de un número racional puede representarse como una expansión decimal de longitud fija.
Veamos más de cerca el decimal en C # que nos lleva al punto flotante decimal en .NET y dado el autor, aceptaré que así es como funciona.
El tipo decimal tiene los mismos componentes que cualquier otro número de coma flotante: una mantisa, un exponente y un signo. Como de costumbre, el signo es solo un bit, pero hay 96 bits de mantisa y 5 bits de exponente. Sin embargo, no todas las combinaciones de exponentes son válidas. Solo los valores del 0 al 28 funcionan, y son efectivamente todos negativos: el valor numérico es . Esto significa que los valores máximos y mínimos del tipo son +/- (2 96 -1), y el número más pequeño que no es cero en términos de magnitud absoluta es 10-28 .sign * mantissa / 10exponent
Señalaré de inmediato que, debido a esta implementación, hay números en el double
tipo que no se pueden representar decimal
, aquellos que están fuera del rango. Double.Epsilon
es lo 4.94065645841247e-324
que no puede representarse en a decimal
, pero puede en a double
.
Sin embargo, dentro del rango que puede representar el decimal, tiene más bits de precisión que otros tipos nativos y puede representarlos sin error.
Hay algunos otros tipos flotando. Hay un BigInteger en C # que puede representar un entero arbitrariamente grande. No hay equivalente al BigDecimal de Java (que puede representar números con dígitos decimales de hasta 2 32 dígitos de largo, que es un rango considerable) exactamente . Sin embargo, si hurgas un poco , puedes encontrar implementaciones enrolladas a mano.
Hay algunos lenguajes que también tienen un tipo de datos racional que le permite representar exactamente los racionales (de modo que 1/3 es en realidad 1/3).
Específicamente para C # y la elección de flotante o racional, diferiré a Jon Skeet de la pinta flotante Decimal en .NET :
La mayoría de las aplicaciones comerciales probablemente deberían estar usando decimal en lugar de flotante o doble. Mi regla general es que los valores hechos por el hombre, como la moneda, generalmente se representan mejor con coma flotante decimal: el concepto de exactamente 1,25 dólares es completamente razonable, por ejemplo. Para valores del mundo natural, como longitudes y pesos, los tipos de punto flotante binario tienen más sentido. A pesar de que existe un "exactamente 1,25 metros" teórico, nunca va a ocurrir en la realidad: ciertamente nunca podrá medir longitudes exactas, y es poco probable que existan incluso a nivel atómico. Estamos acostumbrados a que haya cierta tolerancia involucrada.