Während es einen solchen Operator gibt - **
in Python habe ich mich gefragt, warum Java und C ++ auch keinen haben.
Es ist einfach, eine für Klassen zu erstellen, die Sie in C ++ mit Operatorüberladung definieren (und ich glaube, dass dies auch in Java möglich ist), aber wenn Sie über primitive Typen wie int, double usw. sprechen, müssen Sie library verwenden funktionieren wie Math.power
(und müssen in der Regel beide auf double werfen).
Also - warum nicht einen solchen Operator für primitive Typen definieren?
^
Operators nicht mit der Priorität der Exponentiation übereinstimmt. Betrachten Sie den Ausdrucka + b ^ c
. In der Mathematik wird zuerst die Exponentiation durchgeführt (b ^ c
), dann wird die resultierende Potenz addierta
. In C ++ wird die Addition zuerst ausgeführt (a + b
) und dann der^
Operator mit ausgeführtc
. Selbst wenn Sie den^
Operator als Exponentiation implementiert haben , wird der Vorrang alle überraschen.^
ist ein XOR in C ++. Es wird empfohlen, dass überladene Operatoren nicht anders vorgehen sollten, als ein primitiver Datentyp es verwendet.++
Operator oder den!
Operator et überlastet . al. Exponentation bedeuten. Dies ist jedoch nicht möglich, da die Operatoren, über die Sie sprechen, nur ein Argument akzeptieren. Potenzierung erfordert zwei Argumente.Antworten:
Im Allgemeinen sind die primitiven Operatoren in C (und durch die Erweiterung C ++) so konzipiert, dass sie durch einfache Hardware in ungefähr einer einzigen Anweisung implementiert werden können. So etwas wie Exponentiation erfordert häufig Software-Unterstützung. Es ist also nicht standardmäßig vorhanden.
Es wird auch von der Standardbibliothek der Sprache in Form von bereitgestellt
std::pow
.Schließlich wäre dies für ganzzahlige Datentypen nicht sehr sinnvoll, da die meisten selbst kleinen Werte für die Potenzierung den für int erforderlichen Bereich, dh bis zu 65.535, ausblasen. Sicher, Sie könnten dies für Doubles und Floats tun, aber nicht für Ints, aber warum sollte die Sprache für ein selten verwendetes Feature inkonsistent sein?
quelle
DIV
tut sowohl Division als auch Modul) Sie haben mich jedoch auf den Konsistenzpunkt gebracht.div
oder FORTRAN mit tut.EQ.
); Abhängig von den Sprach-Whitespace-Regeln kann es möglich sein, eine beliebige Anzahl von Operatoren zu haben, ohne dass diese reservierte Wörter sein müssen.Diese Frage ist für C ++ zu beantworten: Stroustrup, "Design and Evolution of C ++", erörtert dies in Abschnitt 11.6.1, S. 247-250.
Es gab allgemeine Einwände gegen das Hinzufügen eines neuen Operators. Es würde die bereits überkomplizierte Rangfolgetabelle ergänzen. Die Mitglieder der Arbeitsgruppe dachten, es würde nur eine geringe Bequemlichkeit bedeuten, eine Funktion zu haben, und sie wollten manchmal ihre eigenen Funktionen ersetzen können.
Es gab keinen guten Kandidaten für einen Betreiber.
^
ist Exklusiv-Oder und^^
lud wegen der Beziehung zwischen&
und|
und&&
und zu Verwirrung ein||
.!
war ungeeignet, da es die natürliche Tendenz geben würde,!=
für die Potenzierung eines vorhandenen Wertes zu schreiben , und das wurde bereits genommen. Das beste*^
, was verfügbar war , hat anscheinend niemand wirklich gemocht.Stroustrup betrachten
**
wieder, aber es hat schon eine Bedeutung in C:a**p
ista
mal was auch immerp
Punkte zu, undchar ** c;
erklärtc
als Zeiger auf Zeiger aufchar
. Das Einführen**
als Token, das "Deklaration eines Zeigers auf Zeiger auf" bedeutet, "mal was das nächste Ding auf" (wenn es ein Zeiger ist) oder "Potenzierung" (wenn gefolgt von einer Zahl) zeigt, verursachte Vorrangprobleme.a/b**p
würde analysieren müssen, alsa/(b**p)
ob p eine Zahl wäre, aber(a/b) * *p
wenn p ein Zeiger wäre, müsste dies im Parser aufgelöst werden.Mit anderen Worten, es wäre möglich gewesen, aber es hätte die Prioritätstabelle und den Parser kompliziert, und beide sind bereits zu kompliziert.
Ich kenne die Geschichte über Java nicht. Ich könnte nur spekulieren. Was C betrifft, so können alle C-Operatoren leicht in Assembler-Code übersetzt werden, um den Compiler zu vereinfachen und um zu vermeiden, dass zeitaufwändige Funktionen in einfachen Operatoren verborgen bleiben (die Tatsache, dass
operator+()
und andere die Komplexität und Leistung beeinträchtigen könnten, war eine der frühen Beschwerden über C ++).quelle
*^
. : Da**p
ist der Killer. (Die Hacks, um dieses Problem zu umgehen ... Brr!)Ich vermute , dass jeder Operator, den Sie einführen, die Komplexität der Sprache erhöht. Die Eintrittsbarriere ist daher sehr hoch. Ich setze Exponentiation sehr, sehr selten ein - und ich bin mehr als glücklich, dafür einen Methodenaufruf zu verwenden.
quelle
x**2
undx**3
nicht so selten verwenden. Und eine magische POW-Implementierung, die der Compiler kennt und für die einfachen Fälle optimiert, wäre schön.x * x
undx * x * x
sind keine schlechten Substitute für das Quadrat und den Würfel.x*x
wenn x ein Ausdruck ist. Im besten Fall wird der Code unhandlich und im schlimmsten Fall langsamer oder sogar falsch. Sie müssen also Ihre eigenen Quadrat- und Würfelfunktionen definieren. Und selbst dann wäre der Code hässlicher als die Verwendung von ** als Netzbetreiber.Die Entwickler der Java-Sprache und der Kernbibliothek haben beschlossen, die meisten mathematischen Operationen in die Klasse Math zu verlagern. Siehe Math.pow () .
Warum? Flexibilität, um Leistung vor Bit-für-Bit-Präzision zu priorisieren. Es widerspricht dem Rest der Sprachspezifikation zu sagen, dass das Verhalten der eingebauten mathematischen Operatoren von Plattform zu Plattform variieren kann, während die Math-Klasse ausdrücklich angibt, dass das Verhalten möglicherweise die Präzision für die Leistung einschränkt.
quelle
Exponentiation war von Anfang an Teil von Fortran, weil es sich ausschließlich um wissenschaftliche Programmierung handelte. Ingenieure und Physiker setzen es häufig in Simulationen ein, da Potenzgesetzbeziehungen in der Physik weit verbreitet sind.
Python ist auch im wissenschaftlichen Rechnen stark vertreten (z. B. NumPy und SciPy). Dies legt zusammen mit dem Potenzierungsoperator nahe, dass es sich auch um eine wissenschaftliche Programmierung handelte.
C, Java und C # haben Wurzeln in der Systemprogrammierung. Vielleicht ist das ein Einfluss, der die Potenzierung aus der Gruppe der unterstützten Operatoren herausgehalten hat.
Nur eine Theorie.
quelle
C definiert nur Operatoren für allgemeine arithmetische Operationen, die mit der ALU zugänglich sind. Das Hauptziel war die Schaffung einer für Menschen lesbaren Schnittstelle zum Assembly-Code.
C ++ änderte kein Operatorverhalten, da die gesamte in C geschriebene Codebasis kompatibel sein sollte.
Java tat dasselbe, weil es vorhandene C ++ - Programmierer nicht einschüchtern wollte.
quelle
Nun, weil jeder Betreiber, der für eine Leistung Sinn macht, bereits im Einsatz ist. ^ ist XOR und ** definiert einen Zeiger auf einen Zeiger. Stattdessen haben sie nur eine Funktion, die dasselbe tut. (wie pow ())
quelle
pow()
Funktion führt ihre Berechnung zur Laufzeit durch, es sei denn, Sie haben einen Compiler, der konstant falten kannpow()
, was ich sehr bezweifle. (Einige Compiler bieten Ihnen jedoch die Möglichkeit, die Berechnung mithilfe von Prozessor-Intrinsics durchzuführen.)*
ist ein lexikalisches Token, egal ob es zur Indirektion oder Multiplikation verwendet wird. Eine**
bedeutungsvolle Potenzierung wäre entweder ein oder zwei lexikalische Token, und Sie möchten wirklich nicht, dass Ihr Lexer die Symboltabelle berührt, um die Token zu setzen.Fakt ist, arithmetische Operatoren sind nur Abkürzungen von Funktionen. (Fast) Alles, was Sie damit machen, können Sie mit einer Funktion machen. Beispiel:
Es ist nur ausführlicher, daher sehe ich nichts Falsches daran, Funktionen zum Ausführen von 'power of' zu verwenden.
quelle
Addition / Subtraktion / Negation und Multiplikation / Division sind grundlegende mathematische Operatoren. Wenn Sie aus Strom einen Betreiber machen würden, wo würden Sie dann aufhören? Quadratwurzeloperator? N-Root-Operator? Logarithmusoperator?
Ich kann nicht für ihre Schöpfer sprechen, aber ich kann sagen, dass es unhandlich und nicht mehr orthogonal wäre, solche Operatoren in der Sprache zu haben. Die Anzahl der nicht alphanumerischen Zeichen / Leerzeichen, die auf der Tastatur verbleiben, ist eher begrenzt. Es ist seltsam, dass es in C ++ einen Modul-Operator gibt.
quelle
mod
seltsam ist , als Operator zu arbeiten. Es ist normalerweise eine einzelne Anweisung. Es ist eine Grundoperation für ganze Zahlen. Es wird fast überall in der Informatik verwendet. (Dinge wie begrenzte Puffer zu implementieren, ohnemod
zu stinken)