Apakah ada operator eksponen di C #?

194

Misalnya, apakah ada operator untuk menangani ini?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

Di masa lalu ^operator telah melayani sebagai operator eksponensial dalam bahasa lain, tetapi dalam C # itu adalah operator yang sedikit bijaksana.

Apakah saya harus menulis lingkaran atau menyertakan namespace lain untuk menangani operasi eksponensial? Jika demikian, bagaimana cara menangani operasi eksponensial menggunakan non-integer?

Charlie
sumber
7
Ini bukan dalam C #, tetapi banyak bahasa digunakan **sebagai operator eksponensial infix.
Mark Rushakoff
datang ke sini karena saya jengkel bahwa 10 ^ 7 disimpan dalam panjang / Int64 memberi saya "13." Saya sudah mencoba 1E7 juga, tapi itu memberi saya kesalahan ketik. Karena saya tidak melihat kesalahan tipe / kesalahan sintaksis operator ilegal, saya berasumsi 10 ^ 7 saya berfungsi ...
mpag
1
@mpag ^ adalah eksklusif atau operator, jadi 10 ^ 7 = 1010b XOR 0111b = 1101b = 13.
Ian Brockbank

Jawaban:

227

Bahasa C # tidak memiliki operator listrik . Namun, .NET Framework menawarkan metode Math.Pow :

Mengembalikan nomor yang ditentukan dinaikkan ke daya yang ditentukan.

Jadi contoh Anda akan terlihat seperti ini:

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);
dtb
sumber
1
Ingatlah penalti kinerja jika menggunakan Math.Pow untuk mengkuadratkan: stackoverflow.com/questions/936541/…
Justas
4
@Justas Saya baru saja mengujinya pada .NET Core 2.1 dan Math.Pow sekarang lebih cepat daripada implementasi alternatif yang disarankan.
bytedev
50

Saya tersandung pada posting ini yang ingin menggunakan notasi ilmiah dalam kode saya, saya menggunakan

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

Tapi setelah itu saya tahu Anda bisa melakukannya

4.95E-10;

Hanya berpikir saya akan menambahkan ini untuk siapa pun dalam situasi yang sama dengan saya.

Jenderal Grey
sumber
34

Ada posting blog di MSDN tentang mengapa operator eksponen TIDAK ada dari tim C #.

Akan mungkin untuk menambahkan operator daya ke bahasa, tetapi melakukan operasi ini adalah hal yang cukup jarang dilakukan di sebagian besar program, dan tampaknya tidak dibenarkan untuk menambahkan operator saat memanggil Math.Pow () sederhana.


Kamu bertanya:

Apakah saya harus menulis lingkaran atau menyertakan namespace lain untuk menangani operasi eksponensial? Jika demikian, bagaimana cara menangani operasi eksponensial menggunakan non-integer?

Math.Pow mendukung parameter ganda sehingga Anda tidak perlu menulis sendiri.

Brian R. Bondy
sumber
24
Saya mengerti argumennya, tetapi alasan yang valid adalah Math.Pow () tidak dapat digunakan untuk menetapkan nilai const, yang membuat eksponen tidak dapat digunakan untuk semua konstanta.
jsmars
1
Seorang operator listrik akan lebih nyaman untuk operator overloading, bagi saya Math.Pow () tidak membenarkan fakta bahwa tidak membuat operator eksponen seperti Math.Pow () bukan operator sehingga tidak memiliki penggunaan yang sama dengan operator ._ .
Alexandre Daubricourt
8

Kurangnya operator eksponensial untuk C # adalah gangguan besar bagi kami ketika mencari bahasa baru untuk mengkonversi perangkat lunak perhitungan kami ke dari vb6 ol yang baik.

Saya senang kami pergi dengan C # tetapi masih mengganggu saya setiap kali saya menulis persamaan kompleks termasuk eksponen. Metode Math.Pow () membuat persamaan cukup sulit untuk membaca IMO.

Solusi kami adalah membuat kelas DoubleX khusus tempat kami menimpa ^ -operator (lihat di bawah)

Ini berfungsi cukup baik selama Anda mendeklarasikan setidaknya satu variabel sebagai DoubleX:

DoubleX a = 2;
DoubleX b = 3;

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

atau gunakan konverter eksplisit pada standar ganda:

double c = 2;
double d = 3;

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

Satu masalah dengan metode ini adalah eksponen dihitung dalam urutan yang salah dibandingkan dengan operator lain. Ini dapat dihindari dengan selalu meletakkan ekstra () di sekitar operasi yang lagi-lagi membuatnya agak sulit untuk membaca persamaan:

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

Saya harap ini dapat membantu orang lain yang menggunakan banyak persamaan kompleks dalam kode mereka, dan mungkin seseorang bahkan memiliki ide tentang bagaimana meningkatkan metode ini ?! :-)

Kelas DoubleX:

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
sumber
2

Saya terkejut tidak ada yang menyebutkan ini, tetapi untuk kasus sederhana (dan mungkin paling banyak ditemui), Anda hanya mengalikannya sendiri.

float Result, Number1;

Result = Number1 * Number1;
Bebek karet
sumber
4
itu bukan multiplikasi, kekuatannya.
Henry
Ya @Henry dan seperti yang disebutkan orang lain, operator tidak ada. Adil Math.Pow. Saya baru saja menawarkan solusi yang jelas untuk kasus yang paling umum.
RubberDuck
4
Juga jauh lebih cepat daripadaMath.Pow(Number1, 2)
lamont
2

Karena belum ada yang menulis fungsi untuk melakukan ini dengan dua bilangan bulat, inilah salah satu caranya:

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

Atau di 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
sumber
Bisakah seseorang tolong jelaskan downvote? Saya telah menguji kode ini dan Anda juga bisa di ideone.com/o9mmAo (C #) & ideone.com/vnaczj (VB.NET) - tampaknya berfungsi dengan baik.
Nathangrad
8
Karena ada Math.Pow jadi kode Anda tidak relevan
Thaina
1
Math.Pow () lambat meskipun dan ini akan jauh lebih cepat asalkan PowerOf cukup kecil.
lamont
3
@Nathangrad Menciptakan kembali roda (persegi) sebagian besar dianggap sebagai anti-pola. FYI: exceptionnotfound.net/…
bytedev
Juga, thre adalah cara yang lebih cepat untuk menerapkan metode kekuatan Anda sendiri. Lihat: en.wikipedia.org/wiki/Exponentiation_by_squaring
Jesse Chisholm
0

Fungsi kekuatan yang baik adalah

    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;
        }
    }

Fungsi `Math.Pow` menggunakan fungsi daya prosesor dan sangat efisien.

Warny
sumber
0

Untuk apa nilainya, saya melewatkan operator ^ ketika menaikkan kekuatan 2 untuk mendefinisikan konstanta biner. Tidak dapat menggunakan Math.Pow () di sana, tetapi menggeser int 1 yang tidak ditandatangani ke kiri oleh nilai eksponen bekerja. Ketika saya perlu mendefinisikan konstanta (2 ^ 24) -1:

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

Ingat jenisnya harus (tidak) << (int).

Graham Gunderson
sumber