145 votes

Pourquoi intpow (int base, int exposant) n'est-il pas inclus dans les bibliothèques standard C ++?

Je sens que je dois juste être incapable de le trouver. Existe-t-il une raison quelconque pour laquelle la fonction p ++ de c ++ n’implémente la fonction "power" que pour les fonctions float et double?

Je sais que la mise en œuvre est triviale, j'ai juste le sentiment de faire un travail qui devrait être dans une bibliothèque standard. Une fonction d’alimentation robuste (c’est-à-dire qui gère les débordements de manière cohérente et explicite) n’est pas amusante à écrire.

81voto

paxdiablo Points 341644

Depuis que je suis ni associé de près avec les créateurs de C et C++ dans les jours de leur création (même si je suis plutôt vieux), ni la partie de la norme ANSI/comités de l'ISO qui a établi les normes, ce n'est pas nécessairement l'opinion de ma part. J'aime à penser qu'il est informé de l'opinion, mais, comme ma femme va vous dire (fréquemment et sans beaucoup d'encouragements nécessaires), j'ai eu tort avant :-)

Supposition, pour ce qu'elle vaut, la façon suivante.

Je soupçonne que la raison de l'original (pré-ANSI) C n'ont pas cette fonctionnalité est parce que c'était totalement inutile. Il y avait déjà une très bonne façon de faire les puissances entières (avec des doubles et puis il suffit de le convertir en un nombre entier, vous donnant la possibilité de vérifier débordement d'entier et de dépassement de capacité avant la conversion).

L'autre chose que vous devez retenir, c'est que l'intention initiale de C, était un des systèmes de langage de programmation, et il est permis de se demander si à virgule flottante est souhaitable dans cette arène de toute façon. Depuis son premier cas d'utilisation était de code UNIX, la virgule flottante aurait été presque inutiles. BCPL, sur ce qui C est fondée, aussi n'avait pas l'utiliser pour des puissances (il n'a pas eu à virgule flottante à tous, à partir de la mémoire).

Comme une part intégrante de la puissance de l'opérateur aurait probablement été un opérateur binaire plutôt qu'un appel de la bibliothèque. Vous n'avez pas ajouter deux entiers avec x = add (y, z) mais avec x = y + z - une partie de la langue appropriée , plutôt que de la bibliothèque.

Depuis la mise en œuvre intégrale de la puissance est relativement simple, il est presque certain que les développeurs de la langue permettrait de mieux utiliser leur temps à fournir plus de choses utiles (voir ci-dessous les commentaires sur le coût d'opportunité).

C'est également pertinente pour le C++. Depuis la mise en œuvre originale a été effectivement juste un traducteur qui produit du code C, il a porté sur les nombreux attributs de C. Son but initial était un C-à-classes, pas du C avec des classes-plus-un-petit-peu-de-extra-mathématiques-stuff.

Pourquoi il n'a jamais été ajoutées aux normes, vous devez vous rappeler que les organismes de normalisation ont des lignes directrices à suivre. Par exemple, en C ANSI a été spécifiquement chargé de codifier la pratique actuelle, pas pour créer une nouvelle langue. Sinon, ils pourraient avoir de fou et nous a donné l'Ada :-)

Plus tard itérations de cette norme ont également des lignes directrices spécifiques et peuvent être trouvés dans les documents justificatifs (les raisons pour lesquelles le comité a formulé un certain nombre de décisions, pas de justification pour la langue elle-même).

Par exemple, le C99 justification document reprend les deux de la C89 principes directeurs qui limite ce qui peut être ajouté:

  • Garder la langue de petite et simple.
  • Fournir seulement une façon de faire une opération.

Lignes directrices (pas nécessairement celles spécifiques ) sont prévues pour les individuels, groupes de travail et donc de limiter le C++ comités (et tous les autres groupes ISO).

En outre, les organismes de normalisation réaliser qu'il y a un coût d'opportunité (économique, terme qui signifie que ce que vous avez à renoncer à une décision rendue) à chaque décision qu'ils prennent. Par exemple, le coût d'opportunité de l'achat de 10 000 dollars pour uber-machine de jeu est des relations cordiales (ou probablement toutes les relations) avec votre autre moitié, environ six mois.

Eric Gunnerson explique cette bien avec son -100 points d'explication quant à pourquoi les choses ne sont pas toujours ajoutée aux produits Microsoft - essentiellement une fonction commence 100 points dans le trou de sorte qu'il doit ajouter un peu de valeur pour être encore considéré.

En d'autres termes, vous avez plutôt une partie intégrante de la puissance de l'opérateur (ce qui, honnêtement, n'importe quel code de singe pourrait attiser en dix minutes) ou multi-threading ajoutées à la norme? Pour moi, je préfère avoir le dernier et pas bricolons avec les différences de mise en œuvre sous UNIX et Windows.

J'aimerais aussi voir des milliers et des milliers de collection de la bibliothèque standard (tables de hachage, les btrees, arbres rouge-noir, le dictionnaire, l'arbitraire des cartes et ainsi de suite), mais, comme la justification états:

Une norme est un traité entre l'analyste et programmeur.

Et le nombre de maîtres d'œuvre sur les corps de normes dépassent de loin le nombre de programmeurs (ou au moins les programmeurs qui ne comprennent pas le coût d'opportunité). Si tout ça a été ajoutée, la prochaine norme C++ serait C++215x et devrait être pleinement mis en œuvre par les développeurs de compilateurs de trois cents ans après que.

De toute façon, c'est mon (assez volumineux) réflexions sur la question. Si seuls les votes ont été remis bases sur la quantité plutôt que la qualité, je serais bientôt souffler tout le monde hors de l'eau. Merci pour l'écoute :-)

44voto

Stephen Canon Points 58003

Pour toute largeur fixe type intégral, près de toutes les paires d'entrée de débordement du type, de toute façon. Quelle est l'utilité de la normalisation d'une fonction qui ne donne pas un résultat utile pour la grande majorité de ses entrées possibles?

Vous devez avoir un grand type entier afin de rendre la fonction utile, et le plus grand entier bibliothèques de fournir la fonction.


Edit: Dans un commentaire sur la question, static_rtti écrit "la Plupart des entrées de provoquer de débordement? Le même est vrai pour l'exp et double pow, je ne vois personne se plaindre." Ceci est incorrect.

Laissons de côté exp, parce que c'est à côté de la question (même si ce serait réellement faire de mon cas plus fort), et de se concentrer sur double pow(double x, double y). Pour quelle partie de (x,y) paires de cette fonction de faire quelque chose d'utile (c'est à dire, pas simplement dépassement supérieur ou inférieur)?

Je vais en fait de se concentrer uniquement sur une petite partie de l'paires d'entrée pour qui pow fait sens, parce que ce sera suffisant pour démontrer mon point de vue: si x est positif et |y| <= 1, alors pow n'a pas de dépassement supérieur ou inférieur. Ce qui compte près d'un quart de tous à virgule flottante paires (exactement la moitié de la non-NaN nombres à virgule flottante sont positifs, et un peu moins de la moitié des non-NaN nombres à virgule flottante ont magnitude inférieure à 1). Évidemment, il y a beaucoup d'autres paires d'entrée pour qui pow produit des résultats utiles, mais nous avons constaté que c'est au moins un quart de toutes les entrées.

Maintenant, regardons une largeur fixe (c'est à dire non-bignum) puissance entière de la fonction. Pour la partie des entrées n'est-il pas tout simplement de débordement? Pour maximiser le nombre de significatif paires d'entrée, la base doit être signé et l'exposant non signé. Supposons que la base et l'exposant sont à la fois n bits de large. Nous pouvons facilement obtenir une borne sur la partie des intrants qui sont significatives:

  • Si l'exposant 0 ou 1, alors toute base est significatif.
  • Si l'exposant est 2 ou plus, alors pas de base de plus de 2^(n/2) produit un résultat significatif.

Ainsi, de la 2^(2n) paires d'entrée, à moins de 2^(n+1) + 2^(3n/2) produire des résultats significatifs. Si nous regardons ce qui est probablement le plus commun de l'utilisation, des nombres entiers de 32 bits, cela signifie que quelque chose de l'ordre de 1/1000e de un pour cent de paires d'entrée ne se contente pas de débordement.

12voto

Parce qu'il n'y a aucun moyen de représenter toutes les puissances entières dans un int:

 >>> print 2**-4
0.0625
 

9voto

phoku Points 1144

C'est effectivement une question intéressante. Un argument que je n'ai pas trouvé dans la discussion, c'est le simple manque évident de retourner des valeurs pour les arguments. Nous allons compter les façons les hypthetical int pow_int(int, int) fonction peut échouer.

  1. Débordement
  2. Résultat indéfini pow_int(0,0)
  3. Le résultat ne peut pas être représentée pow_int(2,-1)

La fonction a au moins 2 modes de défaillance. Les nombres entiers peuvent pas représenter ces valeurs, le comportement de la fonction dans ces cas devraient être définis par la norme et les programmeurs ont besoin d'être conscient de la façon dont exactement la fonction s'occupe de ces cas.

Ensemble en laissant la fonction semble être la seule option raisonnable. Le programmeur peut utiliser la virgule flottante version avec tous les rapports d'erreur possible à la place.

7voto

Bo Persson Points 42821

L'une des raisons pour C++ de ne pas avoir d'autres surcharges afin d'être compatible avec C.

C++98 dispose de fonctions comme double pow(double, int), mais elles ont été supprimées en C++11 avec l'argument que le C99 ne pas les inclure.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3286.html#550

Obtenir un peu plus précise signifie aussi obtenir un peu différente résultat.

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