C # 'da üs operatörü var mı?


194

Örneğin, bununla başa çıkmak için bir operatör var mı?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

Geçmişte, ^operatör diğer dillerde üstel bir operatör olarak hizmet etmişti, ancak C # 'da biraz akıllı bir operatördür.

Üstel işlemleri gerçekleştirmek için bir döngü yazmam veya başka bir ad alanı eklemem gerekir mi? Öyleyse, tamsayı olmayanları kullanarak üstel işlemleri nasıl yapabilirim?


7
C # dilinde değil, ancak birçok dilde **infix üs alma işleci olarak kullanılıyor.
Mark Rushakoff

buraya geldi çünkü ben uzun bir / 1064 depolanan 10 ^ 7 bana "13" verdi miffed. Ben de 1E7 denedim, ama bu bana bir tür hata verdi. Bir tür hata / yasadışı operatör sözdizimi hatası görmediğim için, 10 ^
7'imin

1
@mpag ^ münhasır veya operatördür, bu nedenle 10 ^ 7 = 1010b XOR 0111b = 1101b = 13.
Ian Brockbank

Yanıtlar:


228

C # dilinin bir güç operatörü yok . Ancak, .NET Framework Math.Pow yöntemini sunar :

Belirtilen güce yükseltilen belirli bir sayıyı döndürür.

Yani örneğiniz şöyle görünecektir:

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);


4
@Justas Sadece .NET Core 2.1 ve Math.Pow'da önerilen alternatif uygulamadan daha hızlı olduğunu test ediyorum.
bytedev

50

Kodumda bilimsel gösterimi kullanmak isteyen bu yazıda tökezledim, kullandım

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

Ama daha sonra yapabileceğinizi öğrendim

4.95E-10;

Sadece bunu içinde bulunduğum benzer durumdaki herkes için ekleyeceğimi düşündüm.


34

MSDN'de neden C # ekibinden bir üs operatörü bulunmadığına dair bir blog yazısı var .

Dile bir güç operatörü eklemek mümkün olabilir, ancak bu işlemi gerçekleştirmek çoğu programda yapmak oldukça nadir bir şeydir ve Math.Pow () çağrılırken bir operatör eklemek haklı görünmemektedir .


Sen sordun:

Üstel işlemleri gerçekleştirmek için bir döngü yazmam veya başka bir ad alanı eklemem gerekir mi? Öyleyse, tamsayı olmayanları kullanarak üstel işlemleri nasıl yapabilirim?

Math.Pow çift parametreleri destekler, böylece kendi kodunuzu yazmanıza gerek kalmaz.


24
Argümanı anlıyorum, ancak geçerli bir neden Math.Pow () 'un const değerlerini ayarlamak için kullanılamamasıdır, bu da üsleri tüm sabitler için kullanılamaz hale getirir.
Mart'ta jsmars

1
Bir güç operatörü, operatörün aşırı yüklenmesi için uygun olacaktır, Math.Pow (), Math.Pow () gibi bir üstel operatör yaratmamanın bir operatör olmadığı ve bu nedenle bir operatörle aynı kullanımlara sahip olmadığı gerçeğini haklı çıkarmaz. .
Alexandre Daubricourt

8

C # için üstel bir işleç olmaması, hesaplama yazılımımızı iyi ol 'vb6'dan dönüştürmek için yeni bir dil ararken bizim için büyük bir sıkıntıydı.

C # ile gittik sevindim ama üsleri içeren karmaşık bir denklem yazarken hala beni rahatsız ediyor. Math.Pow () yöntemi, denklemlerin IMO'yu okumasını oldukça zorlaştırır.

Çözümümüz, ^ -operator'ı geçersiz kıldığımız özel bir DoubleX sınıfı oluşturmaktı (aşağıya bakın)

Bu, değişkenlerden en az birini DoubleX olarak beyan ettiğiniz sürece oldukça iyi çalışır:

DoubleX a = 2;
DoubleX b = 3;

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

veya standart çiftlerde açık bir dönüştürücü kullanın:

double c = 2;
double d = 3;

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

Bu yöntemle ilgili bir problem, üssün diğer operatörlere göre yanlış sırada hesaplanmasıdır. Bu, işlemin etrafına her zaman bir denklemin okunmasını biraz daha zorlaştıran bir extra () koyarak önlenebilir:

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

Umarım bu, kodlarında çok sayıda karmaşık denklem kullanan başkalarına yardımcı olabilir ve belki de birinin bu yöntemi nasıl geliştireceği hakkında bir fikri vardır ?! :-)

DoubleX sınıfı:

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

2

Kimsenin bundan bahsetmediğine şaşırdım, ancak basit (ve muhtemelen en çok karşılaşılan) kare için, sadece kendiniz çarpın.

float Result, Number1;

Result = Number1 * Number1;

4
çarpma değil, gücü.
Henry

Evet @ Henry ve diğerlerinin de belirttiği gibi, bir operatör yok. Sadece Math.Pow. En sık karşılaşılan duruma açık bir çözüm öneriyordum.
RubberDuck

4
Ayrıca çok daha hızlıMath.Pow(Number1, 2)
lamont

2

Hiç kimse bunu iki tamsayı ile yapmak için bir işlev yazmadığından, bir yol var:

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

Alternatif olarak VB.NET'te:

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

Birisi downvote açıklayabilir misiniz? Bu kodu test ettim ve siz de ideone.com/o9mmAo (C #) & ideone.com/vnaczj (VB.NET) adresinden de yapabilirsiniz - mükemmel çalışıyor gibi görünüyor.
Nathangrad

8
Math.Pow olduğu için kodunuz önemsiz
Thaina

1
Math.Pow () yavaştır ve PowerOf makul derecede küçük olduğu sürece bu önemli ölçüde daha hızlı olacaktır.
lamont

3
@Nathangrad (Kare) tekerleği yeniden icat etmek büyük ölçüde bir anti-desen olarak kabul edilir. FYI: exceptionnotfound.net/…
bytedev

Ayrıca, kendi güç yönteminizi uygulamak için daha hızlı yollardır. Bakınız: en.wikipedia.org/wiki/Exponentiation_by_squaring
Jesse Chisholm

0

İyi bir güç fonksiyonu

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

`Math.Pow` işlevi işlemci güç işlevini kullanır ve çok daha verimlidir.


0

Değer için ne ben ikili bir sabit tanımlamak için 2 bir güç yükseltirken ^ operatörü özledim. Orada Math.Pow () kullanılamaz, ancak üssün değeri tarafından sola doğru 1 işaretsiz int kaydırılır. (2 ^ 24) -1 sabitini tanımlamam gerektiğinde:

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

Türlerin (uint) << (int) olması gerektiğini unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.