61 votes

Pourquoi l'opérateur électrique en F # ne fonctionne-t-il que pour les nombres à virgule flottante?

Je n’ai jamais vu un exposant ou un opérateur électrique ne prendre que des nombres à virgule flottante?

Par exemple:

2 ** 2 lève une erreur The type 'int' does not support any operators named 'Pow'

Existe-t-il des raisons valables pour cette décision de conception?

36voto

Laurent Points 1803

(**) et pown sont deux choses différentes. Quand vous voyez (**), vous pouvez penser à la formule mathématique à l'aide de logarithmes. Quand vous voyez pown, c'est juste une série de multiplications. Je comprends qu'il peut être surprenant/déroutant au premier abord, parce que la plupart des autres langues ne pas faire une telle différence (surtout parce que les entiers sont souvent implicitement converti en valeurs à virgule flottante). Même en mathématiques, il y a une petite différence: Voir l' article sur Wikipédia, la première définition ne fonctionne que pour des exposants entiers positifs.

Comme ils sont deux différents (mais relative) des choses, ils ont des signatures différentes. Voici (**):

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

Et voici 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 vous créez votre propre type, vous avez seulement besoin d'avoir votre One, (*), et (/) à le faire fonctionner avec pown. La bibliothèque va faire la boucle pour vous (il est optimisé, ce n'est pas de la naïveté O(n)).

Si vous souhaitez utiliser l' (**) opérateur de votre type de non-valeurs intégrales, vous aurez à écrire la logique (et c'est pas le même algorithme que dans pown).

Je pense que c'était une bonne décision de conception de séparer les deux concepts.

9voto

kvb Points 35490

Intégrale de pouvoirs, F# fournit un autre opérateur: pown. Aussi, comme une note de côté, les deux (**) et pown sont surchargés, il est donc parfaitement possible de les utiliser avec d'autres types qui fournissent des membres appropriés (statique Pow méthode dans le cas d' (**); (*) et (/) opérateurs et statique One propriété dans le cas d' pown).

Je ne peux pas vous dire pourquoi l'équipe F# a choisi de ne pas simuler un Pow membre sur int, mais peut-être qu'ils n'ont pas l'impression que c'était urgent car l' pown de l'opérateur peut être utilisé à la place (et depuis qu'il a probablement fait plus de sens à se convertir à flotteur d'abord dans le cas de beaucoup d'opérandes).

2voto

Chris Smith Points 7465

La réponse courte est parce que ce n'est pas très utile pour les types entiers, même les int64. 2 ^ 26 ne vous donne que ~ 1.84467441E19. Donc, si vous aviez deux valeurs X et Y supérieures à 19, par exemple, l’opérateur produira un débordement.

Je conviens que c'est utile pour les petites valeurs, mais ce n'est généralement pas utile pour les types entiers.

2voto

Adam Gent Points 15055

Le langage F# est basé sur est OCaml qui ne fait pas de surcharge d'opérateur ou automatique des données de contrainte (ils préfèrent explicite de la coercition).

Ainsi, même en ajoutant des doubles besoin d'un autre opérateur (+.). Je ne suis pas sûr si c'est là F# obtient sa rigueur sur pour vous, mais je devine que c'est.

Dans la dynamique des langages comme Python ou de Régime, vous obtiendrez de données automatique de la contrainte à un plus grand stockage de données si le nombre est trop grand. Par exemple, vous pourriez avoir des entiers avec des exposants entiers donnant un grand entier pour le résultat.

OCaml et F# qui ont un esprit de type extrême de la sécurité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X