Gibt es einen Exponentenoperator in C #?

194

Gibt es beispielsweise einen Operator, der dies handhabt?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

In der Vergangenheit ^hat der Operator in anderen Sprachen als Exponentialoperator gedient, in C # ist er jedoch ein bitweiser Operator.

Muss ich eine Schleife schreiben oder einen anderen Namespace einfügen, um exponentielle Operationen zu verarbeiten? Wenn ja, wie gehe ich mit Exponentialoperationen mit Nicht-Ganzzahlen um?

Charlie
quelle
7
Es ist nicht in C #, aber viele Sprachen werden **als Infix-Exponentiationsoperator verwendet.
Mark Rushakoff
kam hierher, weil ich verärgert war, dass 10 ^ 7, die in einem langen / Int64 gespeichert waren, mir "13" gaben. Ich hatte auch 1E7 ausprobiert, aber das gab mir einen Tippfehler. Da ich keinen Typfehler / illegalen Operatorsyntaxfehler sah, hatte ich angenommen, dass meine 10 ^ 7 funktionierte ...
mpag
1
@mpag ^ ist der Exklusiv- oder Operator, also 10 ^ 7 = 1010b XOR 0111b = 1101b = 13.
Ian Brockbank

Antworten:

227

Die C # -Sprache hat keinen Energieoperator . Das .NET Framework bietet jedoch die Math.Pow- Methode:

Gibt eine angegebene Zahl zurück, die auf die angegebene Potenz angehoben wurde.

Ihr Beispiel würde also so aussehen:

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);
dtb
quelle
1
Beachten Sie die Leistungseinbußen, wenn Sie Math.Pow zum Quadrieren verwenden: stackoverflow.com/questions/936541/…
Justas
4
@ Justas Ich teste das gerade auf .NET Core 2.1 und Math.Pow ist jetzt schneller als die vorgeschlagene alternative Implementierung.
Bytedev
50

Ich bin über diesen Beitrag gestolpert, um die wissenschaftliche Notation in meinem Code zu verwenden, den ich verwendet habe

4.95*Math.Pow(10,-10);

Aber danach habe ich herausgefunden, dass du es kannst

4.95E-10;

Ich dachte nur, ich würde dies für jeden in einer ähnlichen Situation hinzufügen, in der ich mich befand.

General Gray
quelle
34

Auf MSDN gibt es einen Blog-Beitrag darüber, warum es im C # -Team KEINEN Exponentenoperator gibt .

Es wäre möglich, der Sprache einen Operator hinzuzufügen, aber diese Operation ist in den meisten Programmen ziemlich selten und es scheint nicht gerechtfertigt, einen Operator hinzuzufügen, wenn Math.Pow () aufgerufen wird.


Du hast gefragt:

Muss ich eine Schleife schreiben oder einen anderen Namespace einfügen, um exponentielle Operationen zu verarbeiten? Wenn ja, wie gehe ich mit Exponentialoperationen mit Nicht-Ganzzahlen um?

Math.Pow unterstützt doppelte Parameter, sodass Sie keine eigenen schreiben müssen.

Brian R. Bondy
quelle
24
Ich verstehe das Argument, aber ein triftiger Grund wäre, dass Math.Pow () nicht zum Setzen von Konstantenwerten verwendet werden kann, wodurch Exponenten für alle Konstanten unbrauchbar werden.
Jsmars
1
Ein Energieoperator wäre praktisch für die Überlastung von Operatoren. Für mich rechtfertigt Math.Pow () nicht die Tatsache, dass kein Exponentenoperator erstellt wird, da Math.Pow () kein Operator ist und daher nicht die gleichen Verwendungen wie ein Operator hat ._ .
Alexandre Daubricourt
8

Das Fehlen eines Exponentialoperators für C # war für uns ein großes Ärgernis, als wir nach einer neuen Sprache suchten, in die wir unsere Berechnungssoftware vom guten alten vb6 konvertieren konnten.

Ich bin froh, dass wir uns für C # entschieden haben, aber es nervt mich immer noch, wenn ich eine komplexe Gleichung mit Exponenten schreibe. Die Math.Pow () -Methode macht es ziemlich schwierig, Gleichungen IMO zu lesen.

Unsere Lösung bestand darin, eine spezielle DoubleX-Klasse zu erstellen, in der wir den ^ -Operator überschreiben (siehe unten).

Dies funktioniert ziemlich gut, solange Sie mindestens eine der Variablen als DoubleX deklarieren:

DoubleX a = 2;
DoubleX b = 3;

Console.WriteLine($"a = {a}, b = {b}, a^b = {a ^ b}");

oder verwenden Sie einen expliziten Konverter für Standard-Doubles:

double c = 2;
double d = 3;

Console.WriteLine($"c = {c}, d = {d}, c^d = {c ^ (DoubleX)d}");     // Need explicit converter

Ein Problem bei dieser Methode ist jedoch, dass der Exponent im Vergleich zu anderen Operatoren in der falschen Reihenfolge berechnet wird. Dies kann vermieden werden, indem immer ein zusätzliches () um die Operation gesetzt wird, was das Lesen der Gleichungen wiederum etwas erschwert:

DoubleX a = 2;
DoubleX b = 3;

Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + a ^ b}");        // Wrong result
Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + (a ^ b)}");      // Correct result

Ich hoffe, dass dies anderen helfen kann, die viele komplexe Gleichungen in ihrem Code verwenden, und vielleicht hat sogar jemand eine Idee, wie diese Methode verbessert werden kann?! :-)

DoubleX-Klasse:

using System;

namespace ExponentialOperator
{
    /// <summary>
    /// Double class that uses ^ as exponential operator
    /// </summary>
    public class DoubleX
    {
        #region ---------------- Fields ----------------

        private readonly double _value;

        #endregion ------------- Fields ----------------

        #region -------------- Properties --------------

        public double Value
        {
            get { return _value; }
        }

        #endregion ----------- Properties --------------

        #region ------------- Constructors -------------

        public DoubleX(double value)
        {
            _value = value;
        }

        public DoubleX(int value)
        {
            _value = Convert.ToDouble(value);
        }

        #endregion ---------- Constructors -------------

        #region --------------- Methods ----------------

        public override string ToString()
        {
            return _value.ToString();
        }

        #endregion ------------ Methods ----------------

        #region -------------- Operators ---------------

        // Change the ^ operator to be used for exponents.

        public static DoubleX operator ^(DoubleX value, DoubleX exponent)
        {
            return Math.Pow(value, exponent);
        }

        public static DoubleX operator ^(DoubleX value, double exponent)
        {
            return Math.Pow(value, exponent);
        }

        public static DoubleX operator ^(double value, DoubleX exponent)
        {
            return Math.Pow(value, exponent);
        }

        public static DoubleX operator ^(DoubleX value, int exponent)
        {
            return Math.Pow(value, exponent);
        }

        #endregion ----------- Operators ---------------

        #region -------------- Converters --------------

        // Allow implicit convertion

        public static implicit operator DoubleX(double value)
        {
            return new DoubleX(value);
        }

        public static implicit operator DoubleX(int value)
        {
            return new DoubleX(value);
        }

        public static implicit operator Double(DoubleX value)
        {
            return value._value;
        }

        #endregion ----------- Converters --------------
    }
}
Petter
quelle
2

Ich bin überrascht, dass dies niemand erwähnt hat, aber für den einfachen (und wahrscheinlich am häufigsten anzutreffenden) Fall des Quadrierens multiplizieren Sie einfach mit sich selbst.

float Result, Number1;

Result = Number1 * Number1;
Badeente
quelle
3
es ist keine Multiplikation, seine Kraft von.
Henry
Ja, @Henry und wie andere bereits erwähnt haben, gibt es keinen Operator. Einfach Math.Pow. Ich habe nur eine offensichtliche Lösung für den häufigsten Fall angeboten.
RubberDuck
4
Auch viel schneller alsMath.Pow(Number1, 2)
Lamont
2

Da noch niemand eine Funktion geschrieben hat, um dies mit zwei ganzen Zahlen zu tun, gibt es eine Möglichkeit:

private long CalculatePower(int number, int powerOf)
{
    for (int i = powerOf; i > 1; i--)
        number *= number;
    return number;
}
CalculatePower(5, 3); // 125
CalculatePower(8, 4); // 4096
CalculatePower(6, 2); // 36

Alternativ in VB.NET:

Private Function CalculatePower(number As Integer, powerOf As Integer) As Long
    For i As Integer = powerOf To 2 Step -1
        number *= number
    Next
    Return number
End Function
CalculatePower(5, 3) ' 125
CalculatePower(8, 4) ' 4096
CalculatePower(6, 2) ' 36
Nathangrad
quelle
Kann jemand bitte die Ablehnung erklären? Ich habe diesen Code getestet und Sie können ihn auch unter ideone.com/o9mmAo (C #) & ideone.com/vnaczj (VB.NET) testen - er scheint perfekt zu funktionieren.
Nathangrad
8
Weil es Math.Pow gibt, ist Ihr Code irrelevant
Thaina
1
Math.Pow () ist jedoch langsam und dies wird wesentlich schneller sein, solange PowerOf relativ klein ist.
Lamont
3
@Nathangrad Die Neuerfindung des (quadratischen) Rades wird größtenteils als Anti-Muster angesehen. Zu
Ihrer Information
Es gibt auch schnellere Möglichkeiten, Ihre eigene Stromversorgungsmethode zu implementieren. Siehe: en.wikipedia.org/wiki/Exponentiation_by_squaring
Jesse Chisholm
0

Eine gute Powerfunktion wäre

    public long Power(int number, int power) {
        if (number == 0) return 0;
        long t = number;
        int e = power;
        int result = 1;
        for(i=0; i<sizeof(int); i++) {
            if (e & 1 == 1) result *= t;
            e >>= 1;
            if (e==0) break;
            t = t * t;
        }
    }

Die Funktion "Math.Pow" verwendet die Prozessorleistungsfunktion und ist sehr effizient.

Vorsicht
quelle
0

Für das, was es wert ist, vermisse ich den Operator ^, wenn ich eine Potenz von 2 erhöhe, um eine binäre Konstante zu definieren. Math.Pow () kann dort nicht verwendet werden, aber das Verschieben eines vorzeichenlosen int von 1 um den Wert des Exponenten nach links funktioniert. Als ich eine Konstante von (2 ^ 24) -1 definieren musste:

public static int Phase_count = 24;
public static uint PatternDecimal_Max = ((uint)1 << Phase_count) - 1;

Denken Sie daran, dass die Typen (uint) << (int) sein müssen.

Graham Gunderson
quelle