No es realmente específico para la implementación de Python, pero debería aplicarse a cualquier función de cadena flotante a decimal.
Un número de coma flotante es esencialmente un número binario, pero en notación científica con un límite fijo de cifras significativas.
El inverso de cualquier número que tenga un factor de número primo que no se comparta con la base siempre dará como resultado una representación de punto de punto recurrente. Por ejemplo, 1/7 tiene un factor primo, 7, que no se comparte con 10, y por lo tanto tiene una representación decimal recurrente, y lo mismo es cierto para 1/10 con los factores primos 2 y 5, este último no se comparte con 2 ; Esto significa que 0.1 no puede representarse exactamente por un número finito de bits después del punto de punto.
Como 0.1 no tiene una representación exacta, una función que convierte la aproximación a una cadena de punto decimal generalmente intentará aproximar ciertos valores para que no obtengan resultados no intuitivos como 0.1000000000004121.
Dado que el punto flotante está en notación científica, cualquier multiplicación por una potencia de la base solo afecta a la parte exponente del número. Por ejemplo 1.231e + 2 * 100 = 1.231e + 4 para notación decimal, y de la misma manera, 1.00101010e11 * 100 = 1.00101010e101 en notación binaria. Si multiplico por un no poder de la base, los dígitos significativos también se verán afectados. Por ejemplo 1.2e1 * 3 = 3.6e1
Dependiendo del algoritmo utilizado, puede tratar de adivinar decimales comunes basados solo en cifras significativas. Tanto 0.1 como 0.4 tienen las mismas cifras significativas en binario, porque sus flotadores son esencialmente truncamientos de (8/5) (2 ^ -4) y (8/5) (2 ^ -6) respectivamente. Si el algoritmo identifica el patrón sigfig 8/5 como el decimal 1.6, entonces funcionará en 0.1, 0.2, 0.4, 0.8, etc. También puede tener patrones sigfig mágicos para otras combinaciones, como el flotador 3 dividido por el flotador 10 y otros patrones mágicos estadísticamente propensos a formarse por división por 10.
En el caso de 3 * 0.1, las últimas cifras significativas probablemente serán diferentes de dividir un flotador 3 por el flotador 10, haciendo que el algoritmo no reconozca el número mágico para la constante 0.3 dependiendo de su tolerancia a la pérdida de precisión.
Editar:
https://docs.python.org/3.1/tutorial/floatingpoint.html
Curiosamente, hay muchos números decimales diferentes que comparten la misma fracción binaria aproximada más cercana. Por ejemplo, los números 0.1 y 0.10000000000000001 y 0.1000000000000000055511151231257827021181583404541015625 se aproximan a 3602879701896397/2 ** 55. Dado que todos estos valores decimales comparten la misma aproximación, cualquiera de ellos podría mostrarse mientras se conserva la evaluación invariante (repr) (repr) ) == x.
No hay tolerancia para la pérdida de precisión, si float x (0.3) no es exactamente igual a float y (0.1 * 3), entonces repr (x) no es exactamente igual a repr (y).