Bien qu'il existe un tel opérateur - **
en Python, je me demandais pourquoi Java et C ++ n'en ont pas non plus.
Il est facile d'en créer une pour les classes que vous définissez en C ++ avec surcharge d'opérateur (et je pense qu'une telle chose est également possible en Java), mais lorsque vous parlez de types primitifs tels que int, double et ainsi de suite, vous devrez utiliser la bibliothèque fonctionnent comme Math.power
(et doivent généralement lancer les deux pour doubler).
Alors - pourquoi ne pas définir un tel opérateur pour les types primitifs?
^
opérateur ne correspond pas à la priorité de l'exponentiation. Considérez l'expressiona + b ^ c
. En mathématiques, l'exponentiation est effectuée en premier (b ^ c
), puis la puissance résultante est ajoutée àa
. En C ++, l'addition est effectuée en premier (a + b
) puis l'^
opérateur est effectué avecc
. Donc, même si vous avez implémenté l'^
opérateur pour signifier l'exponentiation, la priorité surprendra tout le monde.^
est un XOR en C ++. Il est conseillé qu'un opérateur surchargé ne fasse pas la différence avec ce qu'un type de données primitif fait en l'utilisant.++
opérateur ou l'!
opérateur et. Al. pour signifier l'exponentation. Mais vous ne pouvez pas de toute façon, car les opérateurs dont vous parlez n'acceptent qu'un seul argument; l'exponentiation nécessite deux arguments.Réponses:
De manière générale, les opérateurs primitifs en C (et par extension C ++) sont conçus pour être implémentables par du matériel simple dans à peu près une seule instruction. Quelque chose comme l'exponentiation nécessite souvent un support logiciel; il n'est donc pas là par défaut.
En outre, il est fourni par la bibliothèque standard de la langue sous la forme de
std::pow
.Enfin, cela pour les types de données entiers n'aurait pas beaucoup de sens, car la plupart des petites valeurs d'exponentiation soufflent la plage requise pour int, c'est-à-dire jusqu'à 65 535. Bien sûr, vous pouvez le faire pour les doubles et les flottants mais pas pour les entiers, mais pourquoi rendre le langage incohérent pour une fonctionnalité rarement utilisée?
la source
DIV
fait à la fois la division et le module).div
ou FORTRAN avec.EQ.
); en fonction des règles d'espace du langage, il peut être possible d'avoir un nombre arbitraire d'opérateurs sans exiger qu'ils soient des mots réservés.Cette question peut être résolue pour C ++: Stroustrup, "Design and Evolution of C ++" en discute dans la section 11.6.1, pp. 247-250.
Il y avait des objections générales à l'ajout d'un nouvel opérateur. Cela ajouterait au tableau de priorité déjà trop compliqué. Les membres du groupe de travail pensaient que cela n'apporterait qu'une commodité mineure à la fonction et ils voulaient parfois pouvoir remplacer leurs propres fonctions.
Il n'y avait pas de bon candidat pour un opérateur.
^
est exclusif-ou, et a^^
invité la confusion en raison de la relation entre&
et|
et&&
et||
.!
était inadapté car il y aurait une tendance naturelle à écrire!=
pour l'exponentiation d'une valeur existante, et cela a déjà été pris. Le meilleur disponible peut avoir été*^
, ce que personne n'a vraiment aimé.Stroustrup a réfléchi à
**
nouveau, mais il a déjà une signification en C:a**p
esta
fois ce quip
pointe vers, etchar ** c;
déclarec
comme un pointeur vers un pointeur verschar
. L'introduction en**
tant que token signifiant "déclaration d'un pointeur vers un pointeur vers", "multiplie par ce que la prochaine chose pointe" (s'il s'agit d'un pointeur) ou "exponentiation" (si elle est suivie d'un nombre) a causé des problèmes de priorité.a/b**p
devrait analyser commea/(b**p)
si p était un nombre, mais(a/b) * *p
si p était un pointeur, cela devrait donc être résolu dans l'analyseur.En d'autres termes, cela aurait été possible, mais cela aurait compliqué la table de priorité et l'analyseur, et les deux sont déjà trop compliqués.
Je ne connais pas l'histoire de Java; je ne pouvais que spéculer. En ce qui concerne C, où il a commencé, tous les opérateurs C sont facilement traduits en code assembleur, en partie pour simplifier le compilateur et en partie pour éviter de cacher des fonctionnalités chronophages dans les opérateurs simples (le fait que
operator+()
et d'autres pourraient masquer une grande complexité et des résultats de performance en était un). des premières plaintes concernant C ++).la source
*^
. : Da**p
est le tueur. (Les astuces pour contourner ce problème… Brr!)Je suppose que c'est parce que chaque opérateur que vous introduisez augmente la complexité de la langue. La barrière à l'entrée est donc très élevée. Je me retrouve à utiliser l'exponentiation très, très rarement - et je suis plus qu'heureux d'utiliser un appel de méthode pour le faire.
la source
x**2
etx**3
pas si rarement. Et une implémentation de Magic Pow que le compilateur connaît et optimise pour les cas simples serait bien.x * x
etx * x * x
ne sont pas de mauvais substituts pour le carré et le cube.x*x
si x est une expression. Dans le meilleur des cas, le code devient lourd et dans le pire, plus lent ou même erroné. Vous devez donc définir vos propres fonctions Square et Cube. Et même alors, le code serait plus laid que d'utiliser ** comme opérateur de puissance.Les concepteurs du langage Java et de la bibliothèque principale ont décidé de reléguer la plupart des opérations mathématiques à la classe Math . Voir Math.pow () .
Pourquoi? Flexibilité pour hiérarchiser les performances sur la précision bit à bit. Il irait à l'encontre du reste des spécifications de langage de dire que le comportement des opérateurs mathématiques intégrés pourrait varier d'une plateforme à l'autre, tandis que la classe Math déclare spécifiquement que le comportement sacrifie potentiellement la précision pour les performances, donc l'acheteur se méfie:
la source
L'exponentiation faisait partie de Fortran depuis le début car elle visait carrément la programmation scientifique. Les ingénieurs et les physiciens l'utilisent souvent dans les simulations, car les relations entre les lois de puissance sont courantes en physique.
Python est également très présent dans le calcul scientifique (par exemple NumPy et SciPy). Cela, avec son opérateur d'exponentiation, suggère qu'il visait également la programmation scientifique.
C, Java et C # ont des racines dans la programmation système. C'est peut-être une influence qui a exclu l'exponentiation du groupe des opérateurs pris en charge.
Juste une théorie.
la source
C uniquement des opérateurs définis pour les opérations arithmétiques courantes accessibles avec l'ALU. Son objectif principal était de créer une interface lisible par l'homme pour le code d'assemblage.
C ++ n'a changé aucun comportement d'opérateur car, il voulait que toute la base de code écrite en C soit conforme.
Java a fait de même car il ne voulait pas intimider les programmeurs C ++ existants.
la source
Eh bien parce que chaque opérateur qui aurait du sens pour une puissance est déjà utilisé. ^ est XOR et ** définit un pointeur vers un pointeur. Au lieu de cela, ils ont juste une fonction qui fait la même chose. (comme pow ())
la source
pow()
fonction effectue son calcul lors de l'exécution, à moins que vous n'ayez un compilateur capable de faire un pliage constantpow()
, ce dont je doute fortement. (Certains compilateurs vous donnent cependant la possibilité d'utiliser les intrinsèques du processeur pour effectuer le calcul.)*
est un jeton lexical, qu'il soit utilisé pour l'indirection ou la multiplication. Une**
exponentiation signifiant serait un ou deux jetons lexicaux, et vous ne voulez vraiment pas que votre lexer doive frapper la table des symboles pour effectuer une tokenisation.Le fait est que les opérateurs arithmétiques ne sont que des raccourcis de fonctions. (Presque) Tout ce que vous faites avec eux peut être fait avec une fonction. Exemple:
C'est juste plus verbeux, donc je ne vois rien de mal à utiliser des fonctions pour effectuer la «puissance de».
la source
L'addition / soustraction / négation et la multiplication / division sont des opérateurs mathématiques de base. Si vous deviez faire de l'électricité un opérateur, où vous arrêteriez-vous? Opérateur racine carrée? Opérateur N-root? Opérateur de logarithme?
Je ne peux pas parler pour leurs créateurs, mais je peux dire que je pense que ce serait devenu lourd et non orthogonal d'avoir de tels opérateurs dans la langue. Le nombre de caractères non alphanumériques / espaces blancs restant sur le clavier est plutôt limité. En l'état, il est étrange qu'il y ait un opérateur de module en C ++.
la source
mod
comme opérateur est étrange. Il s'agit généralement d'une seule instruction. C'est une opération primitive sur des entiers. Il est utilisé presque partout en informatique. (L'implémentation de choses comme des tampons bornés sansmod
puerait)