Есть ли оператор степени в C #?

195

Например, существует ли оператор для обработки этого?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

В прошлом ^оператор служил в качестве экспоненциального оператора в других языках, но в C # это побитовый оператор.

Нужно ли писать цикл или включать другое пространство имен для обработки экспоненциальных операций? Если да, то как мне обрабатывать экспоненциальные операции, используя нецелые числа?

Чарли
источник
7
Это не в C #, но многие языки используют **в качестве оператора возведения в степень infix.
Марк Рушаков
пришел сюда, потому что я был раздражен, что 10 ^ 7, хранящийся в long / Int64, давал мне «13». Я также пробовал 1E7, но это дало мне ошибку типа. Так как я не видел ошибку типа / недопустимая синтаксическая ошибка оператора, я предположил, что мои 10 ^ 7 работали ...
mpag
1
@mpag ^ - эксклюзив или оператор, поэтому 10 ^ 7 = 1010b XOR 0111b = 1101b = 13.
Ян Брокбэнк

Ответы:

229

В языке C # нет оператора power . Однако .NET Framework предлагает метод Math.Pow :

Возвращает указанное число, возведенное в указанную степень.

Итак, ваш пример будет выглядеть так:

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);
DTB
источник
1
Имейте в виду снижение производительности при использовании Math.Pow для возведения в квадрат: stackoverflow.com/questions/936541/…
Justas
4
@Justas Я только что протестировал это на .NET Core 2.1 и Math.Pow теперь быстрее, чем предлагаемая альтернативная реализация.
bytedev
50

Я наткнулся на этот пост, пытаясь использовать научную нотацию в моем коде, я использовал

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

Но потом я узнал, что вы можете сделать

4.95E-10;

Просто подумал, что добавлю это для любого в подобной ситуации, в которой я был.

Генерал Грей
источник
34

В MSDN есть запись в блоге о том, почему оператор степени не существует из команды C #.

Можно было бы добавить оператор power к языку, но выполнение этой операции довольно редко в большинстве программ, и не представляется оправданным добавлять оператор при вызове Math.Pow () просто.


Ты спрашивал:

Нужно ли писать цикл или включать другое пространство имен для обработки экспоненциальных операций? Если да, то как мне обрабатывать экспоненциальные операции, используя нецелые числа?

Math.Pow поддерживает двойные параметры, поэтому вам не нужно писать свои собственные.

Брайан Р. Бонди
источник
24
Я понимаю аргумент, но действительной причиной будет то, что Math.Pow () не может использоваться для установки значений констант, что делает экспоненты непригодными для всех констант.
Jsmars
1
Оператор мощности был бы удобен для перегрузки операторов, для меня Math.Pow () не оправдывает тот факт, что не создается оператор экспоненты, так как Math.Pow () не является оператором и, следовательно, не имеет такого же использования, как оператор ._ ,
Александр Добрикур
8

Отсутствие экспоненциального оператора для C # было большим раздражением для нас, когда мы искали новый язык для преобразования нашего программного обеспечения для вычислений из хорошего старого v6.

Я рад, что мы пошли с C #, но это все еще раздражает меня всякий раз, когда я пишу сложное уравнение, включая показатели. Метод Math.Pow () затрудняет чтение уравнений IMO.

Нашим решением было создать специальный класс DoubleX, в котором мы переопределяем оператор ^ (см. Ниже)

Это работает довольно хорошо, если вы объявите хотя бы одну из переменных как DoubleX:

DoubleX a = 2;
DoubleX b = 3;

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

или используйте явный конвертер для стандартных пар:

double c = 2;
double d = 3;

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

Одна из проблем этого метода заключается в том, что показатель степени вычисляется в неправильном порядке по сравнению с другими операторами. Этого можно избежать, всегда добавляя в операцию extra (), что снова затрудняет чтение уравнений:

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

Я надеюсь, что это может помочь другим, кто использует много сложных уравнений в своем коде, и, возможно, кто-то даже имеет представление о том, как улучшить этот метод ?! :-)

Класс 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
источник
2

Я удивлен, что никто не упомянул об этом, но для простого (и, вероятно, наиболее часто встречающегося) случая возведения в квадрат вы просто умножаете сами.

float Result, Number1;

Result = Number1 * Number1;
Резиновая утка
источник
4
это не умножение, его сила.
Генри
Да, @Henry и, как уже упоминалось, оператор не существует. Просто Math.Pow. Я просто предлагал очевидное решение для наиболее распространенного случая.
RubberDuck
4
Также намного быстрее чемMath.Pow(Number1, 2)
lamont
2

Так как никто еще не написал функцию для этого с двумя целыми числами, вот один из способов:

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

Альтернативно в 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
источник
Может кто-нибудь, пожалуйста, объясните отрицательный голос? Я проверил этот код, и вы тоже можете это сделать на ideone.com/o9mmAo (C #) и ideone.com/vnaczj (VB.NET) - кажется, он работает отлично.
Натанград
8
Потому что есть Math.Pow, так что ваш код не имеет значения
Thaina
1
Math.Pow () работает медленно, но будет значительно быстрее, если PowerOf достаточно мал.
Lamont
3
@ Натанград Изобретая (квадратное) колесо в значительной степени считается анти-шаблон. К вашему сведению: exceptionnotfound.net/…
bytedev
Кроме того, есть более быстрые способы реализовать свой собственный метод питания. См .: en.wikipedia.org/wiki/Exponentiation_by_squaring
Джесси Чисхолм,
0

Хорошая функция мощности будет

    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` использует функцию мощности процессора и является более эффективной.

Warny
источник
0

Для чего стоит пропустить оператор ^ при увеличении степени 2 для определения двоичной константы. Там нельзя использовать Math.Pow (), но смещение беззнакового целого числа 1 влево на значение показателя степени работает. Когда мне нужно было определить константу (2 ^ 24) -1:

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

Помните, что типы должны быть (uint) << (int).

Грэм Гандерсон
источник