Existe um operador expoente em c #?


194

Por exemplo, existe um operador para lidar com isso?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

No passado, o ^operador serviu como operador exponencial em outros idiomas, mas em C # é um operador em termos de bits.

Preciso escrever um loop ou incluir outro espaço para nome para lidar com operações exponenciais? Em caso afirmativo, como lidar com operações exponenciais usando não-inteiros?


7
Não está em C #, mas muitos idiomas são usados **como operador de exponenciação de infixos.
Mark Rushakoff

vim aqui porque fiquei ofendido que 10 ^ 7 armazenados em um longo / Int64 estava me dando "13." Eu tentei o 1E7 também, mas isso me deu um erro de tipo. Como eu não estava vendo a / erro de sintaxe operador ilegal tipo de erro, eu tinha assumido o meu 10 ^ 7 estava trabalhando ...
MPAG

1
@mpag ^ é o operador exclusivo, então 10 ^ 7 = 1010b XOR 0111b = 1101b = 13.
Ian Brockbank

Respostas:


227

A linguagem C # não possui um operador de energia . No entanto, o .NET Framework oferece o método Math.Pow :

Retorna um número especificado aumentado para a energia especificada.

Portanto, seu exemplo seria assim:

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);

1
Tenha em mente a penalidade de desempenho se estiver usando Math.pow para quadratura: stackoverflow.com/questions/936541/...
Justas

4
@ Justas Acabei de testar isso no .NET Core 2.1 e Math.Pow agora é mais rápido que a implementação alternativa sugerida.
Bydevev

50

Eu tropecei neste post procurando usar notação científica no meu código, eu usei

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

Mas depois eu descobri que você pode fazer

4.95E-10;

Apenas pensei em adicionar isso para qualquer pessoa em uma situação semelhante à que eu estivesse.


34

Há uma postagem de blog no MSDN sobre por que um operador de expoente NÃO existe da equipe de C #.

Seria possível adicionar um operador de energia ao idioma, mas executar esta operação é algo bastante raro na maioria dos programas, e não parece justificado adicionar um operador ao chamar Math.Pow () é simples.


Você perguntou:

Preciso escrever um loop ou incluir outro espaço para nome para lidar com operações exponenciais? Em caso afirmativo, como lidar com operações exponenciais usando não-inteiros?

Math.Pow suporta parâmetros duplos, para que você não precise escrever seus próprios.


24
Eu entendo o argumento, mas uma razão válida seria que Math.Pow () não pode ser usado para definir valores constantes, o que torna os expoentes inutilizáveis ​​para todas as constantes.
jsmars

1
Um operador de energia seria conveniente para a sobrecarga do operador, para mim o Math.Pow () não justifica o fato de não criar um operador expoente, já que Math.Pow () não é um operador e, portanto, não tem os mesmos usos que um operador. .
Alexandre Daubricourt

8

A falta de um operador exponencial para C # foi um grande aborrecimento para nós, quando procuramos um novo idioma para converter nosso software de cálculo do bom e velho vb6.

Fico feliz por termos escolhido C #, mas isso ainda me incomoda sempre que estou escrevendo uma equação complexa, incluindo expoentes. O método Math.Pow () torna as equações bastante difíceis de ler IMO.

Nossa solução foi criar uma classe DoubleX especial em que substituímos o operador ^ (veja abaixo)

Isso funciona razoavelmente, desde que você declare pelo menos uma das variáveis ​​como DoubleX:

DoubleX a = 2;
DoubleX b = 3;

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

ou use um conversor explícito em duplos padrão:

double c = 2;
double d = 3;

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

Um problema com esse método, porém, é que o expoente é calculado na ordem errada em comparação com outros operadores. Isso pode ser evitado sempre colocando um extra () em torno da operação, o que novamente torna um pouco mais difícil a leitura das equações:

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

Espero que isso ajude outras pessoas que usam muitas equações complexas em seu código, e talvez alguém até tenha uma idéia de como melhorar esse método ?! :-)

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

2

Estou surpreso que ninguém tenha mencionado isso, mas para o caso simples (e provavelmente o mais encontrado) de quadratura, você apenas se multiplica.

float Result, Number1;

Result = Number1 * Number1;

4
não é multiplicação, é poder de.
Henry

Sim @Henry e, como outros já mencionaram, um operador não existe. Apenas Math.Pow. Eu estava apenas oferecendo uma solução óbvia para o caso mais comum.
precisa

4
Também muito mais rápido que oMath.Pow(Number1, 2)
lamont

2

Como ninguém ainda escreveu uma função para fazer isso com dois números inteiros, aqui está uma maneira:

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

Como alternativa no 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

Alguém pode explicar o voto negativo? Testei esse código e você também pode em ideone.com/o9mmAo (C #) e ideone.com/vnaczj (VB.NET) - ele parece funcionar perfeitamente bem.
Nathangrad

8
Porque há Math.pow para que o seu código é irrelevância
Thaina

1
Math.Pow () é lento e isso será substancialmente mais rápido desde que o PowerOf seja razoavelmente pequeno.
26417

3
@ Nathangrad Reinventar a roda (quadrada) é amplamente considerado um antipadrão. FYI: exceptionnotfound.net/…
bytedev

Além disso, existem três maneiras mais rápidas de implementar seu próprio método de energia. Vejo: en.wikipedia.org/wiki/Exponentiation_by_squaring
Jesse Chisholm

0

Uma boa função de potência seria

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

A função `Math.Pow` usa a função de energia do processador e é altamente mais eficiente.


0

Pelo que vale a pena, sinto falta do operador ^ ao elevar uma potência de 2 para definir uma constante binária. Não é possível usar Math.Pow () lá, mas mudar um int não assinado de 1 para a esquerda pelo valor do expoente funciona. Quando eu precisava definir uma constante de (2 ^ 24) -1:

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

Lembre-se de que os tipos devem ser (uint) << (int).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.