Ir al contenido principal

Operadores aritméticos y lógicos

Introducción

Los operadores son símbolos especiales que nos permiten realizar operaciones sobre variables y valores en nuestro código. En C#, al igual que en la mayoría de los lenguajes de programación, disponemos de diversos tipos de operadores que nos ayudan a manipular datos de forma eficiente. En este artículo, nos centraremos en dos categorías fundamentales: los operadores aritméticos, que nos permiten realizar cálculos matemáticos, y los operadores lógicos, que nos ayudan a evaluar condiciones y tomar decisiones en nuestro programa.

Dominar estos operadores es esencial para cualquier programador, ya que constituyen herramientas básicas para el procesamiento de datos y la implementación de la lógica de negocio en aplicaciones. A lo largo de este artículo, veremos cómo funcionan estos operadores en C# y cómo podemos utilizarlos en situaciones prácticas.

Operadores aritméticos

Los operadores aritméticos son aquellos que nos permiten realizar operaciones matemáticas con valores numéricos. C# ofrece un conjunto completo de operadores que cubren todas las necesidades básicas de cálculo.

Operadores básicos

Los cinco operadores aritméticos fundamentales en C# son:

Operador Nombre Descripción
+ Suma Suma dos operandos
- Resta Resta el segundo operando del primero
* Multiplicación Multiplica dos operandos
/ División Divide el primer operando por el segundo
% Módulo Devuelve el resto de la división entre el primer operando y el segundo

Es importante tener en cuenta que cuando realizamos una división entre dos números enteros, el resultado será también un entero, truncándose cualquier parte decimal. Para obtener un resultado con decimales, al menos uno de los operandos debe ser de tipo decimal, float o double.

Veamos algunos ejemplos:

// Declaramos algunas variables para nuestros ejemplos
int a = 10;
int b = 3;

// Suma (+)
int suma = a + b;     // Resultado: 13
Console.WriteLine($"Suma: {a} + {b} = {suma}");

// Resta (-)
int resta = a - b;    // Resultado: 7
Console.WriteLine($"Resta: {a} - {b} = {resta}");

// Multiplicación (*)
int multiplicacion = a * b;    // Resultado: 30
Console.WriteLine($"Multiplicación: {a} * {b} = {multiplicacion}");

// División (/)
int division = a / b;    // Resultado: 3 (división entera)
Console.WriteLine($"División entera: {a} / {b} = {division}");

// Módulo o resto (%)
int modulo = a % b;    // Resultado: 1 (el resto de 10/3)
Console.WriteLine($"Módulo: {a} % {b} = {modulo}");

// División con resultado decimal
double divisionDecimal = (double)a / b;    // Resultado: 3.3333...
Console.WriteLine($"División decimal: {a} / {b} = {divisionDecimal}");

Operadores de incremento y decremento

Los operadores de incremento y decremento permiten aumentar o disminuir el valor de una variable en una unidad.

Operador Nombre Descripción
++ Incremento Aumenta el valor de la variable en 1
-- Decremento Disminuye el valor de la variable en 1

Estos operadores pueden usarse de dos formas distintas:

  • Prefijo (++x, --x): Primero se incrementa o decrementa el valor y luego se utiliza en la expresión.
  • Sufijo (x++, x--): Primero se utiliza el valor original en la expresión y después se incrementa o decrementa.

Esta distinción es importante cuando estos operadores se utilizan en expresiones más complejas:

int contador = 5;

// Incremento (++)
contador++;    // Equivale a: contador = contador + 1
Console.WriteLine($"Después de incremento: {contador}");    // Resultado: 6

// Decremento (--)
contador--;    // Equivale a: contador = contador - 1
Console.WriteLine($"Después de decremento: {contador}");    // Resultado: 5

// Demostración de la diferencia entre prefijo y sufijo
int x = 5;
int y;

// Prefijo: incrementa primero, luego asigna
y = ++x;    // x se incrementa a 6, luego y = 6
Console.WriteLine($"Prefijo: x = {x}, y = {y}");    // x = 6, y = 6

// Reiniciamos x
x = 5;

// Sufijo: asigna primero, luego incrementa
y = x++;    // y = 5, luego x se incrementa a 6
Console.WriteLine($"Sufijo: x = {x}, y = {y}");    // x = 6, y = 5

Operadores de asignación compuesta

Los operadores de asignación compuesta combinan una operación aritmética con la asignación, proporcionando una sintaxis más concisa.

Operador Nombre Equivalencia
+= Suma y asignación x += y es igual a x = x + y
-= Resta y asignación x -= y es igual a x = x - y
*= Multiplicación y asignación x *= y es igual a x = x * y
/= División y asignación x /= y es igual a x = x / y
%= Módulo y asignación x %= y es igual a x = x % y

Estos operadores no solo hacen que el código sea más compacto, sino que también pueden ser más eficientes, ya que la variable solo se evalúa una vez:

int valor = 10;

// Suma y asignación
valor += 5;    // Equivale a: valor = valor + 5
Console.WriteLine($"Después de +=: {valor}");    // Resultado: 15

// Resta y asignación
valor -= 3;    // Equivale a: valor = valor - 3
Console.WriteLine($"Después de -=: {valor}");    // Resultado: 12

// Multiplicación y asignación
valor *= 2;    // Equivale a: valor = valor * 2
Console.WriteLine($"Después de *=: {valor}");    // Resultado: 24

// División y asignación
valor /= 4;    // Equivale a: valor = valor / 4
Console.WriteLine($"Después de /=: {valor}");    // Resultado: 6

// Módulo y asignación
valor %= 4;    // Equivale a: valor = valor % 4
Console.WriteLine($"Después de %=: {valor}");    // Resultado: 2

Operadores lógicos

Los operadores lógicos nos permiten evaluar condiciones y trabajar con valores booleanos (true/false). Son fundamentales para la toma de decisiones en nuestros programas.

Operadores de comparación

Los operadores de comparación evalúan la relación entre dos valores y devuelven un resultado booleano.

Operador Nombre Descripción
== Igual a Comprueba si dos valores son iguales
!= Diferente de Comprueba si dos valores son diferentes
> Mayor que Comprueba si el primer valor es mayor que el segundo
< Menor que Comprueba si el primer valor es menor que el segundo
>= Mayor o igual que Comprueba si el primer valor es mayor o igual que el segundo
<= Menor o igual que Comprueba si el primer valor es menor o igual que el segundo

Estos operadores son esenciales para establecer condiciones en estructuras de control como if, while, etc.:

int x = 10;
int y = 5;

// Igual a (==)
bool esIgual = (x == y);    // Resultado: false
Console.WriteLine($"{x} == {y}: {esIgual}");

// Diferente de (!=)
bool esDiferente = (x != y);    // Resultado: true
Console.WriteLine($"{x} != {y}: {esDiferente}");

// Mayor que (>)
bool esMayor = (x > y);    // Resultado: true
Console.WriteLine($"{x} > {y}: {esMayor}");

// Menor que (<)
bool esMenor = (x < y);    // Resultado: false
Console.WriteLine($"{x} < {y}: {esMenor}");

// Mayor o igual que (>=)
bool esMayorIgual = (x >= y);    // Resultado: true
Console.WriteLine($"{x} >= {y}: {esMayorIgual}");

// Menor o igual que (<=)
bool esMenorIgual = (x <= y);    // Resultado: false
Console.WriteLine($"{x} <= {y}: {esMenorIgual}");

Operadores lógicos booleanos

Los operadores lógicos booleanos permiten combinar condiciones y realizar operaciones de lógica booleana.

Operador Nombre Descripción
&& AND lógico Devuelve true si ambos operandos son true
|| OR lógico Devuelve true si al menos uno de los operandos es true
! NOT lógico Invierte el valor booleano de su operando

Tabla de verdad para operadores lógicos

Para entender completamente el comportamiento de estos operadores, es útil consultar sus tablas de verdad:

Tabla de verdad para el operador AND (&&):

A B A && B
true true true
true false false
false true false
false false false

Tabla de verdad para el operador OR (||):

A B A || B
true true true
true false true
false true true
false false false

Tabla de verdad para el operador NOT (!):

A !A
true false
false true

Veamos algunos ejemplos de cómo se utilizan estos operadores:

bool condicion1 = true;
bool condicion2 = false;

// AND lógico (&&): devuelve true si ambas condiciones son true
bool resultadoAnd = condicion1 && condicion2;    // Resultado: false
Console.WriteLine($"{condicion1} && {condicion2}: {resultadoAnd}");

// OR lógico (||): devuelve true si al menos una condición es true
bool resultadoOr = condicion1 || condicion2;    // Resultado: true
Console.WriteLine($"{condicion1} || {condicion2}: {resultadoOr}");

// NOT lógico (!): invierte el valor de la condición
bool resultadoNot = !condicion1;    // Resultado: false
Console.WriteLine($"!{condicion1}: {resultadoNot}");

Evaluación de cortocircuito

Una característica importante de los operadores lógicos && y || es que realizan evaluación de cortocircuito. Esto significa que:

  • Para &&: Si la primera condición es false, no se evalúa la segunda (porque el resultado será false independientemente).
  • Para ||: Si la primera condición es true, no se evalúa la segunda (porque el resultado será true independientemente).

Esta propiedad es útil para optimizar el rendimiento y evitar posibles errores:

int num = 5;

// Ejemplo de cortocircuito con &&
// Si num < 0 es false, no se evaluará la división (evitando posible división por cero)
if (num != 0 && 10 / num > 1)
{
    Console.WriteLine("La condición se cumple y no hay división por cero");
}

// Ejemplo de cortocircuito con ||
// Si num > 0 es true, no se evaluará la segunda condición
if (num > 0 || SomeExpensiveOperation())
{
    Console.WriteLine("Al menos una condición es verdadera");
}

// Función de ejemplo (en realidad no se llamará debido al cortocircuito)
bool SomeExpensiveOperation()
{
    Console.WriteLine("Esta operación es costosa y no se ejecutará si no es necesario");
    return true;
}

Operadores a nivel de bits

Los operadores a nivel de bits permiten manipular valores individuales de bits en números enteros. Aunque son menos comunes en la programación cotidiana, son importantes para ciertas aplicaciones específicas.

Operador Nombre Descripción
& AND a nivel de bits Realiza AND bit a bit entre operandos
| OR a nivel de bits Realiza OR bit a bit entre operandos
^ XOR a nivel de bits Realiza XOR bit a bit entre operandos
~ NOT a nivel de bits Invierte todos los bits del operando
<< Desplazamiento a la izquierda Desplaza bits a la izquierda
>> Desplazamiento a la derecha Desplaza bits a la derecha

Para entender estos operadores, es útil visualizar los números en su representación binaria:

int a = 5;  // En binario: 0101
int b = 3;  // En binario: 0011

// AND a nivel de bits (&)
int andBits = a & b;    // Resultado: 1 (binario: 0001)
Console.WriteLine($"{a} & {b} = {andBits}");

// OR a nivel de bits (|)
int orBits = a | b;    // Resultado: 7 (binario: 0111)
Console.WriteLine($"{a} | {b} = {orBits}");

// XOR a nivel de bits (^)
int xorBits = a ^ b;    // Resultado: 6 (binario: 0110)
Console.WriteLine($"{a} ^ {b} = {xorBits}");

// NOT a nivel de bits (~)
int notBits = ~a;    // Invierte todos los bits
Console.WriteLine($"~{a} = {notBits}");

// Desplazamiento a la izquierda (<<)
int shiftLeft = a << 1;    // Resultado: 10 (binario: 1010)
Console.WriteLine($"{a} << 1 = {shiftLeft}");

// Desplazamiento a la derecha (>>)
int shiftRight = a >> 1;    // Resultado: 2 (binario: 0010)
Console.WriteLine($"{a} >> 1 = {shiftRight}");

Precedencia de operadores

En C#, como en la mayoría de los lenguajes de programación, existe un orden de precedencia que determina qué operadores se evalúan primero cuando hay varios en una misma expresión. La siguiente tabla muestra el orden de precedencia, de mayor a menor:

Categoría Operadores
Primarios (), [], ., x++ (posfijo), x-- (posfijo)
Unarios +, -, !, ~, ++x (prefijo), --x (prefijo), (T)x (conversión)
Multiplicativos *, /, %
Aditivos +, -
Desplazamiento <<, >>
Relacionales <, >, <=, >=
Igualdad ==, !=
AND a nivel de bits &
XOR a nivel de bits ^
OR a nivel de bits |
AND lógico &&
OR lógico ||
Condicional ?:
Asignación =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=

Es importante entender esta precedencia para evitar resultados inesperados. Cuando tengas dudas sobre el orden de evaluación, puedes usar paréntesis para hacerlo explícito:

// Sin paréntesis, el resultado podría ser confuso
int resultado1 = 2 + 3 * 4;    // Resultado: 14 (no 20)
Console.WriteLine($"2 + 3 * 4 = {resultado1}");

// Con paréntesis, dejamos clara nuestra intención
int resultado2 = (2 + 3) * 4;    // Resultado: 20
Console.WriteLine($"(2 + 3) * 4 = {resultado2}");

Ejemplo práctico: calculadora simple

Veamos cómo podemos aplicar estos conocimientos en una pequeña aplicación de consola que funciona como una calculadora básica:

using System;

class CalculadoraSimple
{
    static void Main()
    {
        Console.WriteLine("¡Bienvenido a la Calculadora C#!");
        
        // Solicitar valores al usuario
        Console.Write("Introduce el primer número: ");
        double num1 = Convert.ToDouble(Console.ReadLine());
        
        Console.Write("Introduce el segundo número: ");
        double num2 = Convert.ToDouble(Console.ReadLine());
        
        // Mostrar menú de operaciones
        Console.WriteLine("\nOperaciones disponibles:");
        Console.WriteLine("1. Suma");
        Console.WriteLine("2. Resta");
        Console.WriteLine("3. Multiplicación");
        Console.WriteLine("4. División");
        Console.WriteLine("5. Resto (módulo)");
        
        Console.Write("\nSelecciona una operación (1-5): ");
        int opcion = Convert.ToInt32(Console.ReadLine());
        
        // Variable para almacenar el resultado
        double resultado = 0;
        bool operacionValida = true;
        
        // Realizar la operación seleccionada
        switch (opcion)
        {
            case 1:
                resultado = num1 + num2;
                Console.WriteLine($"\nSuma: {num1} + {num2} = {resultado}");
                break;
            case 2:
                resultado = num1 - num2;
                Console.WriteLine($"\nResta: {num1} - {num2} = {resultado}");
                break;
            case 3:
                resultado = num1 * num2;
                Console.WriteLine($"\nMultiplicación: {num1} * {num2} = {resultado}");
                break;
            case 4:
                // Comprobar división por cero
                if (num2 != 0)
                {
                    resultado = num1 / num2;
                    Console.WriteLine($"\nDivisión: {num1} / {num2} = {resultado}");
                }
                else
                {
                    Console.WriteLine("\nError: No se puede dividir por cero");
                    operacionValida = false;
                }
                break;
            case 5:
                // Comprobar módulo por cero
                if (num2 != 0)
                {
                    resultado = num1 % num2;
                    Console.WriteLine($"\nMódulo: {num1} % {num2} = {resultado}");
                }
                else
                {
                    Console.WriteLine("\nError: No se puede calcular el módulo con divisor cero");
                    operacionValida = false;
                }
                break;
            default:
                Console.WriteLine("\nOpción no válida");
                operacionValida = false;
                break;
        }
        
        // Verificaciones adicionales con operadores lógicos
        if (operacionValida)
        {
            if (resultado > 0)
            {
                Console.WriteLine("El resultado es positivo");
            }
            else if (resultado < 0)
            {
                Console.WriteLine("El resultado es negativo");
            }
            else
            {
                Console.WriteLine("El resultado es cero");
            }
            
            // Comprobar si el resultado es par o impar (solo para enteros)
            if (resultado == Math.Floor(resultado))
            {
                bool esPar = (resultado % 2 == 0);
                Console.WriteLine(esPar ? "El resultado es un número par" : "El resultado es un número impar");
            }
        }
        
        Console.WriteLine("\nGracias por usar la Calculadora C#");
    }
}

Este ejemplo utiliza tanto operadores aritméticos para realizar los cálculos, como operadores lógicos para las comprobaciones de condiciones, mostrando cómo se pueden combinar ambos tipos en aplicaciones reales.

Resumen

En este artículo hemos explorado los operadores aritméticos y lógicos en C#, herramientas fundamentales para realizar cálculos y evaluaciones condicionales en nuestro código. Hemos visto cómo los operadores aritméticos nos permiten realizar operaciones matemáticas básicas, mientras que los operadores lógicos nos ayudan a trabajar con valores booleanos y tomar decisiones en nuestros programas.

Dominar estos operadores es esencial para avanzar en tu aprendizaje de C#, ya que constituyen la base para implementar la lógica de negocio en cualquier aplicación. En próximos artículos, veremos cómo estos operadores se combinan con estructuras de control para crear programas más complejos y funcionales.