Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os operadores a seguir executam operações aritméticas com operandos de tipos numéricos:
- Operadores unários
++(mais) e--(menos) - Operadores binários (multiplicação),
*
Todos os tipos numéricos integrais e de vírgula flutuante suportam estes operadores.
Os inttipos , uint, long, e ulong definem todos esses operadores. Os outros tipos integrais (sbyte, byte, short, ushort, e char) definem apenas os operadores ++ e --. Para os outros operadores, quando os operandos são dos tipos integrais sbyte, byte, short, ushort ou char, os seus valores são convertidos para o tipo int e o tipo de resultado é int. Quando os operandos são de diferentes tipos integrais ou de vírgula flutuante, seus valores são convertidos para o tipo de contenção mais próximo, se tal tipo existir. Para obter mais informações, consulte a seção Promoções numéricas da especificação da linguagem C#. Os ++ operadores e -- são definidos para todos os tipos numéricos integrais e de vírgula flutuante e o tipo char . O tipo de resultado de uma expressão de atribuição composta é o tipo do operando esquerdo.
Operador de incremento ++
O operador ++ de incremento unário incrementa seu operando em 1. O operando deve ser uma variável, um acesso de propriedade ou um acesso de indexador .
O operador de incremento é suportado de duas formas: o operador de incremento postfix, x++e o operador de incremento de prefixo, ++x.
Operador de incremento Postfix
O resultado de é o valor de antesx++operação, como mostra o exemplo a x seguir:
int i = 3;
Console.WriteLine(i); // output: 3
Console.WriteLine(i++); // output: 3
Console.WriteLine(i); // output: 4
Operador de incremento de prefixo
O resultado de ++x é o valor de após a operação, como mostra o exemplo a xseguir:
double a = 1.5;
Console.WriteLine(a); // output: 1.5
Console.WriteLine(++a); // output: 2.5
Console.WriteLine(a); // output: 2.5
Operador de decréscimo --
O operador -- de decréscimo unário diminui seu operando em 1. O operando deve ser uma variável, um acesso de propriedade ou um acesso de indexador .
O operador de decréscimo é suportado de duas formas: o operador de decréscimo postfix, x--e o operador de decréscimo prefixo, --x.
Operador de decréscimo Postfix
O resultado de é o valor de antesx--operação, como mostra o exemplo a x seguir:
int i = 3;
Console.WriteLine(i); // output: 3
Console.WriteLine(i--); // output: 3
Console.WriteLine(i); // output: 2
Operador de decréscimo de prefixo
O resultado de --x é o valor de após a operação, como mostra o exemplo a xseguir:
double a = 1.5;
Console.WriteLine(a); // output: 1.5
Console.WriteLine(--a); // output: 0.5
Console.WriteLine(a); // output: 0.5
Unary mais e menos operadores
O operador unário + retorna o valor de seu operando. O operador unário - calcula a negação numérica de seu operando.
Console.WriteLine(+4); // output: 4
Console.WriteLine(-4); // output: -4
Console.WriteLine(-(-4)); // output: 4
uint a = 5;
var b = -a;
Console.WriteLine(b); // output: -5
Console.WriteLine(b.GetType()); // output: System.Int64
Console.WriteLine(-double.NaN); // output: NaN
O tipo ulong não suporta o operador unário - .
Operador de multiplicação *
O operador * de multiplicação calcula o produto de seus operandos:
Console.WriteLine(5 * 2); // output: 10
Console.WriteLine(0.5 * 2.5); // output: 1.25
Console.WriteLine(0.1m * 23.4m); // output: 2.34
O operador unário * é o operador indirection do ponteiro.
Operador de divisão /
O operador / de divisão divide seu operando esquerdo pelo operando direito.
Divisão inteira
Para os operandos de tipos inteiros, o / resultado do operador é de um tipo inteiro e é igual ao quociente dos dois operandos arredondados para zero:
Console.WriteLine(13 / 5); // output: 2
Console.WriteLine(-13 / 5); // output: -2
Console.WriteLine(13 / -5); // output: -2
Console.WriteLine(-13 / -5); // output: 2
Para obter o quociente dos dois operandos como um número de vírgula flutuante, use o float, doubleou decimal digite:
Console.WriteLine(13 / 5.0); // output: 2.6
int a = 13;
int b = 5;
Console.WriteLine((double)a / b); // output: 2.6
Divisão de vírgula flutuante
Para o float, doublee decimal tipos, o resultado do operador é o / quociente dos dois operandos:
Console.WriteLine(16.8f / 4.1f); // output: 4.097561
Console.WriteLine(16.8d / 4.1d); // output: 4.09756097560976
Console.WriteLine(16.8m / 4.1m); // output: 4.0975609756097560975609756098
Se um dos operandos é decimal, outro operando não pode ser float nem double, porque nem float nem double são implicitamente conversíveis para decimal. Você deve converter explicitamente o float operando ou double para o decimal tipo. Para obter mais informações sobre conversões entre tipos numéricos, consulte Conversões numéricas internas.
Operador remanescente %
O operador % restante calcula o restante depois de dividir seu operando esquerdo por seu operando direito.
Inteiro restante
Para os operandos de tipos inteiros, o resultado de a % b é o valor produzido por a - (a / b) * b. O sinal do restante diferente de zero é o mesmo que o sinal do operando esquerdo, como mostra o exemplo a seguir:
Console.WriteLine(5 % 4); // output: 1
Console.WriteLine(5 % -4); // output: 1
Console.WriteLine(-5 % 4); // output: -1
Console.WriteLine(-5 % -4); // output: -1
Use o método para calcular a divisão inteira e os Math.DivRem resultados restantes.
Remanescente de vírgula flutuante
Para os float e double operandos, o resultado de x % y para o finito x e y é o valor z tal que
- O sinal de , se diferente de
zzero, é o mesmo que o sinal dex. - O valor absoluto de
zé o valor produzido por|x| - n * |y|ondené o maior inteiro possível que é menor ou igual a|x| / |y|e|x|e|y|são os valores absolutos dexey, respetivamente.
Nota
Este método de cálculo do restante é análogo ao método usado para operandos inteiros, mas diferente da especificação IEEE 754. Se você precisar da operação restante que esteja em conformidade com a especificação IEEE 754, use o Math.IEEERemainder método.
Para obter informações sobre o % comportamento do operador com operandos não finitos, consulte a seção Operador restante da especificação da linguagem C#.
Para os decimal operandos, o operador % restante é equivalente ao operador restante do System.Decimal tipo.
O exemplo a seguir demonstra o comportamento do operador restante com operandos de ponto flutuante:
Console.WriteLine(-5.2f % 2.0f); // output: -1.2
Console.WriteLine(5.9 % 3.1); // output: 2.8
Console.WriteLine(5.9m % 3.1m); // output: 2.8
Operador de adição +
O operador + de adição calcula a soma de seus operandos:
Console.WriteLine(5 + 4); // output: 9
Console.WriteLine(5 + 4.3); // output: 9.3
Console.WriteLine(5.1m + 4.2m); // output: 9.3
Você também pode usar o + operador para concatenação de cadeia de caracteres e combinação de delegação. Para obter mais informações, consulte o + artigo e += operadores .
Operador de subtração -
O operador - de subtração subtrai seu operando direito do operando esquerdo:
Console.WriteLine(47 - 3); // output: 44
Console.WriteLine(5 - 4.3); // output: 0.7
Console.WriteLine(7.5m - 2.3m); // output: 5.2
Você também pode usar o - operador para remoção de delegado. Para obter mais informações, consulte o - artigo e -= operadores .
Atribuição composta
Para um operador opbinário , uma expressão de atribuição composta do formulário
x op= y
É equivalente a
x = x op y
Só que x só é avaliada uma vez.
O exemplo a seguir demonstra o uso de atribuição composta com operadores aritméticos:
int a = 5;
a += 9;
Console.WriteLine(a); // output: 14
a -= 4;
Console.WriteLine(a); // output: 10
a *= 2;
Console.WriteLine(a); // output: 20
a /= 4;
Console.WriteLine(a); // output: 5
a %= 3;
Console.WriteLine(a); // output: 2
Devido a promoções numéricas, o op resultado da operação pode não ser implicitamente conversível para o tipo T de x. Nesse caso, se op for um operador predefinido e o resultado da operação for explicitamente conversível para o tipo T de , uma expressão de xatribuição composta do formulário x op= y é equivalente a x = (T)(x op y), exceto que x é avaliada apenas uma vez. O exemplo a seguir demonstra esse comportamento:
byte a = 200;
byte b = 100;
var c = a + b;
Console.WriteLine(c.GetType()); // output: System.Int32
Console.WriteLine(c); // output: 300
a += b;
Console.WriteLine(a); // output: 44
No exemplo anterior, value 44 é o resultado da conversão de value 300 para o byte tipo.
Nota
No contexto de verificação de estouro verificado, o exemplo anterior lança um OverflowExceptionarquivo . Para obter mais informações, consulte a seção Estouro aritmético de inteiros.
Você também usa os += operadores e -= para se inscrever e cancelar a assinatura de um evento, respectivamente. Para obter mais informações, consulte Como se inscrever e cancelar a assinatura de eventos.
Precedência e associatividade do operador
A lista a seguir ordena operadores aritméticos a partir da maior precedência para a mais baixa:
- Operadores de incremento e decréscimo
x++x--Postfix - Incremento
++xe decréscimo--xde prefixo e unário+e-operadores - Multiplicativo
*,/e%operadores -
+Aditivos e-operadores
Os operadores aritméticos binários são associados à esquerda. Ou seja, operadores com o mesmo nível de precedência são avaliados da esquerda para a direita.
Use parênteses, (), para alterar a ordem de avaliação imposta pela precedência do operador e associatividade.
Console.WriteLine(2 + 2 * 2); // output: 6
Console.WriteLine((2 + 2) * 2); // output: 8
Console.WriteLine(9 / 5 / 2); // output: 0
Console.WriteLine(9 / (5 / 2)); // output: 4
Para obter a lista completa de operadores C# ordenados por nível de precedência, consulte a seção Precedência do operador do artigo Operadores C#.
Estouro aritmético e divisão por zero
Quando o resultado de uma operação aritmética está fora do intervalo de possíveis valores finitos do tipo numérico envolvido, o comportamento de um operador aritmético depende do tipo de seus operandos.
Estouro aritmético inteiro
A divisão inteira por zero sempre lança um DivideByZeroException.
Se ocorrer estouro aritmético de inteiros, o contexto de verificação de estouro, que pode ser verificado ou desmarcado, controla o comportamento resultante:
- Em um contexto verificado, se o estouro acontecer em uma expressão constante, ocorrerá um erro em tempo de compilação. Caso contrário, quando a operação é executada em tempo de execução, um OverflowException é lançado.
- Em um contexto não verificado, o resultado é truncado descartando quaisquer bits de ordem alta que não se encaixam no tipo de destino.
Junto com as instruções verificadas e não verificadas , você pode usar os checked operadores e unchecked para controlar o contexto de verificação de estouro, no qual uma expressão é avaliada:
int a = int.MaxValue;
int b = 3;
Console.WriteLine(unchecked(a + b)); // output: -2147483646
try
{
int d = checked(a + b);
}
catch(OverflowException)
{
Console.WriteLine($"Overflow occurred when adding {a} to {b}.");
}
Por padrão, as operações aritméticas ocorrem em um contexto não verificado .
Estouro aritmético de vírgula flutuante
As operações aritméticas com os float tipos e double nunca lançam uma exceção. O resultado de operações aritméticas com esses tipos pode ser um dos valores especiais que representam infinito e não-um-número:
double a = 1.0 / 0.0;
Console.WriteLine(a); // output: Infinity
Console.WriteLine(double.IsInfinity(a)); // output: True
Console.WriteLine(double.MaxValue + double.MaxValue); // output: Infinity
double b = 0.0 / 0.0;
Console.WriteLine(b); // output: NaN
Console.WriteLine(double.IsNaN(b)); // output: True
Para os operandos do tipo, o decimal estouro aritmético sempre lança um OverflowException. Divisão por zero sempre lança um DivideByZeroException.
Erros de arredondamento
Devido a limitações gerais da representação de números reais e aritmética de vírgula flutuante, erros de arredondamento podem ocorrer em cálculos com tipos de vírgula flutuante. Ou seja, o resultado produzido de uma expressão pode diferir do resultado matemático esperado. O exemplo a seguir demonstra vários desses casos:
Console.WriteLine(.41f % .2f); // output: 0.00999999
double a = 0.1;
double b = 3 * a;
Console.WriteLine(b == 0.3); // output: False
Console.WriteLine(b - 0.3); // output: 5.55111512312578E-17
decimal c = 1 / 3.0m;
decimal d = 3 * c;
Console.WriteLine(d == 1.0m); // output: False
Console.WriteLine(d); // output: 0.9999999999999999999999999999
Para obter mais informações, consulte comentários nas páginas de referência System.Double, System.Single ou System.Decimal .
Capacidade de sobrecarga do operador
Um tipo definido pelo usuário pode sobrecarregar os operadores aritméticos unários (++, --, +, e -) e binários (*, /, %+, e -). Quando um operador binário está sobrecarregado, o operador de atribuição composto correspondente também é implicitamente sobrecarregado. A partir do C# 14, um tipo definido pelo usuário pode sobrecarregar explicitamente os operadores de atribuição compostos (op=) para fornecer uma implementação mais eficiente. Normalmente, um tipo sobrecarrega esses operadores porque o valor pode ser atualizado no local, em vez de alocar uma nova instância para armazenar o resultado da operação. Se um tipo não fornecer uma sobrecarga explícita, o compilador gerará a sobrecarga implícita.
Operadores verificados definidos pelo usuário
Quando sobrecarregas um operador aritmético, podes usar a checked palavra-chave para definir a versão verificada desse operador. O exemplo a seguir mostra como fazer isso:
public record struct Point(int X, int Y)
{
public static Point operator checked +(Point left, Point right)
{
checked
{
return new Point(left.X + right.X, left.Y + right.Y);
}
}
public static Point operator +(Point left, Point right)
{
return new Point(left.X + right.X, left.Y + right.Y);
}
}
Ao definir um operador verificado, você também deve definir o operador correspondente sem o checked modificador. O operador verificado é chamado em um contexto verificado, o operador sem o checked modificador é chamado em um contexto não verificado.
Quando se definem ambas as versões de um operador, o seu comportamento só difere quando o resultado de uma operação é demasiado grande para ser representado no tipo de resultado da seguinte forma:
- Um operador verificado lança um OverflowExceptionarquivo .
- Um operador sem o
checkedmodificador retorna uma instância que representa um resultado truncado .
Para obter informações sobre a diferença no comportamento dos operadores aritméticos internos, consulte a seção Estouro aritmético e divisão por zero .
Você pode usar o checked modificador somente quando sobrecarregar qualquer um dos seguintes operadores:
- Unário
++,--, e-operadores - Binário
*,/,+e-operadores - Atribuições compostas
*=,/=,+=e-=operadores (C# 14 e posterior) - Operadores de conversão explícitos
Nota
A presença do checked modificador não afeta o contexto de verificação de overflow dentro do seu corpo. O contexto padrão é definido pelo valor da opção de compilador CheckForOverflowUnderflow. Use as checked and unchecked para especificar explicitamente o contexto de verificação de estouro, como demonstra o exemplo no início desta seção.
Especificação da linguagem C#
Para obter mais informações, consulte as seguintes seções da especificação da linguagem C#:
- Operadores de incremento e decréscimo Postfix
- Operadores de incremento e decréscimo de prefixo
- Unary plus operador
- Unary menos operador
- Operador de multiplicação
- Operador de divisão
- Operador restante
- Operador de adição
- Operador de subtração
- Atribuição composta
- Os operadores controlados e não controlados
- Promoções numéricas
- Atribuição composta definida pelo usuário