resueltos que punto numeros normalizado normalizada norma mantisa informatica flotante exponente ejercicios ejemplos coma f# language-design

que - ¿Por qué el operador de potencia en F#solo trabaja con números de punto flotante?



punto flotante normalizado (4)

El lenguaje en el que se basa F # es OCaml, que no realiza la sobrecarga del operador ni la coacción automática de datos (prefieren la coacción explícita).

Por lo tanto, incluso agregar dobles requiere un operador diferente (+.). No estoy seguro de que aquí sea donde F # tenga su rigor, pero supongo que sí.

En lenguajes dinámicos como Python o Scheme, obtendría la coacción automática de datos para un mayor almacenamiento de datos si el número fuera demasiado grande. Por ejemplo, podría tener enteros con exponentes enteros que den un entero grande para el resultado.

OCaml y F # tienen un espíritu de seguridad de tipo extremo.

Nunca he visto que un lenguaje tenga un exponente o un operador de potencia tomando números de punto flotante.

Por ejemplo:

2 ** 2 arroja un error The type ''int'' does not support any operators named ''Pow''

¿Hay razones válidas para esta decisión de diseño?


La respuesta corta es porque no es muy útil para tipos enteros, incluso para int64s. 2 ^ 26 solo te da ~ 1.84467441E19. Entonces, si tiene dos valores, X e Y, ambos mayores que 19, entonces el operador de energía resultará en un desbordamiento.

Estoy de acuerdo en que es útil para valores pequeños, sin embargo, generalmente no es útil para tipos enteros.


Para las potencias integrales, F # proporciona otro operador: pown . Además, como nota al margen, tanto (**) como pown están sobrecargados, por lo que es perfectamente posible usarlos con otros tipos que proporcionen miembros apropiados (un método Pow estático en el caso de (**) ; (*) y (/) Operadores y una propiedad One estática en el caso de pown ).

No puedo hablar sobre por qué el equipo de F # optó por no simular a un miembro de Pow en int , pero quizás no sintieron que era urgente ya que el operador pown podría usarse en su lugar (y dado que probablemente tiene más sentido convertir a flotar Primero en el caso de grandes operandos).


(**) Y pown son dos cosas diferentes. Cuando ve (**) , puede pensar en la fórmula matemática usando logaritmos. Cuando ves pown , es solo una serie de multiplicaciones. Entiendo que puede ser sorprendente / confuso al principio, porque la mayoría de los otros idiomas no hacen tal diferencia (principalmente porque los enteros a menudo se convierten implícitamente a valores de punto flotante). Incluso en matemáticas, hay una pequeña diferencia: consulte la entrada de Wikipedia , la primera definición funciona solo para los exponentes enteros positivos.

Como son dos cosas diferentes (pero relacionadas), tienen firmas diferentes. Aquí está (**) :

^a -> ( ^b -> ^a) when ^a : (static member Pow : ^a * ^b -> ^a)

Y aquí está pown :

^a -> (int -> ^a) when ^a : (static member get_One : -> ^a) and ^a : (static member ( * ) : ^a * ^a -> ^a) and ^a : (static member ( / ) : ^a * ^a -> ^a)

Si creas tu propio tipo, solo necesitas tener tu One , (*) y (/) para que funcione con pown . La biblioteca hará el bucle por usted (está optimizado, no es el ingenuo O (n)).

Si desea utilizar el operador (**) en su tipo para valores no integrales, tendrá que escribir la lógica completa (y no será el mismo algoritmo que en pown ).

Creo que fue una buena decisión de diseño separar los dos conceptos.