stringtranslate.com

Torre numérica

En Scheme y en los dialectos Lisp inspirados en él, la torre numérica es un conjunto de tipos de datos que representan números y una lógica para su organización jerárquica.

Una representación de la torre numérica con cinco tipos de números.

Cada tipo en la torre conceptualmente "se asienta" sobre un tipo más fundamental, por lo que un entero es un número racional y un número , pero lo inverso no es necesariamente cierto, es decir, no todos los números son enteros. Esta asimetría implica que un lenguaje puede permitir con seguridad coerciones implícitas de tipos numéricos (sin crear problemas semánticos) en una sola dirección: convertir un entero en un racional no pierde información y nunca influirá en el valor devuelto por una función, pero convertir la mayoría de los números reales en un entero alteraría cualquier cálculo relevante (por ejemplo, el real 1/3 no es igual a ningún entero) y, por lo tanto, es inadmisible.

En Lisp

Básicamente, la torre numérica está diseñada para codificar las propiedades de la teoría de conjuntos de los números en un lenguaje fácil de implementar: cada entero es un racional con un denominador implícito de 1, y todos los reales son complejos con una parte imaginaria implícita de 0. En la práctica, la implementación puede ahorrar tiempo y espacio al ignorar estas propiedades a menos que se vuelvan aritméticamente relevantes, y también puede mejorar correspondientemente la eficiencia de su representación al reducir los valores numéricos a su representación canónica al eliminar los componentes insignificantes de un número.

El tipo más genérico, number, tiene un nombre un tanto confuso: existe para capturar todos los valores matemáticos cuyo tipo es más general que complex , pero que aún se pueden usar con operaciones matemáticas estándar, como se define en Scheme. Por lo tanto, captura, por ejemplo, infinito positivo y negativo ( +inf.0y -inf.0, el mantisa aquí significa aproximación hasta la cardinalidad), ya que esos son objetos matemáticos a los que al menos algunas operaciones numéricas pueden aplicarse válidamente (por ejemplo, uno puede sumar o multiplicar por infinito, obteniendo infinito; o comparar cardinalidad contra infinito, siendo infinito siempre mayor que cualquier valor finito). [1] En un nivel más técnico, numberen Lisp simplemente proporciona un lugar en la jerarquía de tipos para los tipos de valores no estrictamente numéricos definidos por IEEE 754 .

El lenguaje de programación Scheme define toda su aritmética dentro de este modelo, al igual que la mayoría de los otros dialectos Lisp. [2] [3] Algunas implementaciones pueden extender o adaptar la torre. Kawa , una implementación de Scheme para la JVM , extiende la torre para incluir tanto cuaterniones [4] como cantidades, [5] siendo las cantidades una forma de subtipificar valores numéricos con unidades; por ejemplo, una cantidad de gramos no se puede sumar de manera significativa a una cantidad de metros porque, a través de las cantidades, los números heredan la lógica derivada del análisis dimensional para gobernar su significado en relación con los demás y, por lo tanto, sus interacciones aritméticas válidas.

Otra variación común es soportar versiones tanto exactas como inexactas de la torre o partes de ella; R 7 RS Scheme recomienda pero no requiere estrictamente esto de las implementaciones. En este caso, se utiliza una semántica similar para determinar la permisibilidad de la coerción implícita: la inexactitud es una propiedad contagiosa de los números, [6] y cualquier operación numérica que involucre valores exactos e inexactos debe producir valores de retorno inexactos de al menos la misma precisión que el número inexacto más preciso que aparece en la expresión, a menos que la precisión sea prácticamente infinita (por ejemplo, que contenga un repetend detectable ), o a menos que pueda probarse que la precisión del resultado de la operación es independiente de la inexactitud de cualquiera de sus operandos (por ejemplo, una serie de multiplicaciones donde al menos un multiplicando es 0).

En otros idiomas

La mayoría de los lenguajes de programación y sus implementaciones no admiten una torre numérica como la de Scheme, aunque algunos lenguajes proporcionan un soporte limitado o inconsistente si la simplicidad de la implementación lo permite. Python , por ejemplo, proporciona una estructura similar a través de PEP3141, [7] citando el ejemplo de Scheme, aunque en la práctica los números racionales ( fractions) deben importarse desde su propio módulo, y tanto los números racionales como los complejos utilizan una sintaxis ligeramente variante de los literales numéricos normales, ya que la sintaxis de Python es menos explícita que la de Lisp.

Así en los siguientes ejemplos de esquema vemos:

1 -2 +3 1 -2 3 1/3 1/3 72/6+8/3i 12+8/3i ; coerción: forma canónica ( + 3+2i 2-2i ) 5 ; coerción: forma canónica ( - 3-62/32i 1+inf.0i ) 2-inf.0i ; coerción: cardinalidad infinita ( > 3+0/2i 3 ) #f ; coerción: 3 ≯ 3                    

Mientras que en los siguientes ejemplos de Python vemos:

1 ;  - 2 ;  + 3  1  - 2  3 1 / 3  0.3333333333333333 inf  =  float ( 'inf' )  # infinito no es de primera clase from  fracciones  import  Fracción x  =  Fracción ( 1 ,  3 ) y  =  Fracción ( 2 ,  3 ) x  +  y  Fracción ( 1 ,  1 )  # sin coerción ( 3 + 2 j )  ( 3 + 2 j ) complex ( x ,  inf )  ( 0.3333333333333333 + infj )  # coerción: igualdad violada a  =  1 / 3 b  =  Fracción ( 1 ,  3 ) caz  =  complex ( a ,  0 ) cbz  =  complex ( b ,  0 ) a  ==  b  Falso caz  ==  cbz  Verdadero  # prueba de violación de igualdad complex ( x  +  y ,  - inf )  ( 1 - infj )  # coerción: igualdad preservada ( 3 + 0 j )  >  3  Traceback  ( última  llamada reciente  ): Archivo "<stdin>" , línea 1 , en < módulo > # sin coerción: error de tipo TypeError : '>' no es compatible entre instancias de 'complex' e 'int'                  

En los ejemplos de Python, podemos ver que surgen libremente problemas numéricos con una aplicación inconsistente de la semántica de su coerción de tipos. Mientras que 1 / 3en Python se trata como una llamada a dividir 1 por 3, lo que da como resultado un número de punto flotante, la inclusión de números racionales dentro de un número complejo, aunque claramente permisible, los convierte implícitamente de números racionales a números de punto flotante o enteros, incluso en casos en los que esto es incorrecto.

Smalltalk es otro lenguaje de programación que sigue este modelo, pero tiene ArithmeticValue y Magnitude como superclases de Number.

Referencias

  1. ^ "Informe revisado7 sobre el esquema de lenguaje algorítmico: 6.2.4: Extensiones de implementación" (PDF) .
  2. ^ "Informe revisado5 sobre el esquema de lenguaje algorítmico: 6.2.1: Tipos numéricos" (PDF) .
  3. ^ "Informe revisado7 sobre el esquema de lenguaje algorítmico: 6.2.1: Tipos numéricos" (PDF) .
  4. ^ "Documentación de referencia de Kawa: 12.4. Cuaterniones".
  5. ^ "Documentación de referencia de Kawa: 12.5 Cantidades y unidades".
  6. ^ "Informe revisado7 sobre el esquema de lenguaje algorítmico: 6.2.2: Exactitud" (PDF) .
  7. ^ "PEP 3141 – Una jerarquía de tipos para números".