Capítulo 4: Operaciones y expresiones en C#
5 min de lectura
Parte I - Sección 1: Fundamentos de C# - Nivel: Principiante
Objetivos de aprendizaje
Al finalizar este capítulo serás capaz de:
- Usar operadores aritméticos avanzados para cálculos complejos
- Aplicar operadores de comparación para evaluar condiciones
- Combinar operadores lógicos para expresiones complejas
- Entender la precedencia de operadores en expresiones
- Construir expresiones matemáticas complejas para ingeniería eléctrica
Requisitos previos
Antes de comenzar este capítulo debes:
- Haber completado el Capítulo 3
- Entender qué son las variables
- Conocer los tipos básicos (int, double, string, bool)
- Saber declarar y asignar valores a variables
Proyecto del capítulo
Sistema de Verificación de Instalación Eléctrica
Al final de este capítulo habrás construido un script que:
- Verifica si un circuito cumple con normas técnicas
- Compara valores medidos con límites permitidos
- Calcula caídas de tensión y las valida
- Genera reportes de conformidad con múltiples condiciones
Tiempo estimado: 40-50 minutos
Contenido
1. Introducción: De cálculos simples a expresiones complejas
En el capítulo anterior vimos operaciones básicas:
double resistencia = voltaje / corriente;
double potencia = voltaje * corriente;
En este capítulo aprenderás a construir expresiones más complejas que combinan múltiples operaciones y condiciones, como las que usas en ingeniería:
- Verificar rangos: ¿El voltaje está entre 207V y 253V? (230V ±10%)
- Validar condiciones: ¿La caída de tensión es menor al 3% Y la corriente no excede el límite?
- Cálculos complejos: Potencia trifásica, factor de corrección, dimensionado de cables
2. Operadores aritméticos avanzados
Ya conoces los básicos: +, -, *, /. Veamos operadores adicionales y técnicas útiles.
2.1 Módulo (%) - Resto de división
El operador módulo % devuelve el resto de una división entera.
int total = 17;
int grupo = 5;
int resto = total % grupo; // 2 (17 ÷ 5 = 3 con resto 2)
Casos prácticos:
Ejemplo 1: Detectar si un número es par o impar
int numeroCable = 24;
int resto = numeroCable % 2;
if (resto == 0)
{
// Es par
}
else
{
// Es impar
}
Ejemplo 2: Distribuir cables en bandejas
int totalCables = 47;
int capacidadBandeja = 12;
int bandejasCompletas = totalCables / capacidadBandeja; // 3
int cablesEnUltimaBandeja = totalCables % capacidadBandeja; // 11
// Necesitas 4 bandejas (3 completas + 1 parcial)
2.2 Operadores de incremento y decremento
Para aumentar o disminuir una variable en 1:
int contador = 10;
contador++; // contador = contador + 1 → 11
contador--; // contador = contador - 1 → 10
Dos formas: prefijo y postfijo
int a = 5;
int b = ++a; // Primero incrementa, luego asigna: a=6, b=6
int c = 5;
int d = c++; // Primero asigna, luego incrementa: c=6, d=5
En la práctica, úsalos en líneas separadas para claridad:
int erroresEncontrados = 0;
// Encontraste un error
erroresEncontrados++;
// Encontraste otro
erroresEncontrados++;
// erroresEncontrados ahora es 2
2.3 Operadores de asignación compuesta
Atajos para operaciones frecuentes:
int cantidad = 10;
cantidad += 5; // cantidad = cantidad + 5 → 15
cantidad -= 3; // cantidad = cantidad - 3 → 12
cantidad *= 2; // cantidad = cantidad * 2 → 24
cantidad /= 4; // cantidad = cantidad / 4 → 6
cantidad %= 5; // cantidad = cantidad % 5 → 1
Ejemplo práctico: Acumular valores
double potenciaTotal = 0.0;
double motor1 = 7.5; // kW
double motor2 = 11.0; // kW
double motor3 = 5.5; // kW
potenciaTotal += motor1; // 7.5
potenciaTotal += motor2; // 18.5
potenciaTotal += motor3; // 24.0 kW
2.4 Potencias y raíces (Math)
Para operaciones matemáticas avanzadas, usa la clase Math:
// Potencia: Math.Pow(base, exponente)
double area = Math.Pow(5, 2); // 5² = 25
// Raíz cuadrada
double lado = Math.Sqrt(25); // √25 = 5
// Raíz cúbica (elevar a 1/3)
double volumen = 27;
double arista = Math.Pow(volumen, 1.0/3.0); // ∛27 = 3
Caso práctico: Cálculo de potencia trifásica
double voltaje = 400.0; // V línea-línea
double corriente = 50.0; // A
double factorPotencia = 0.85;
// P = √3 × V × I × cos φ
double potencia = Math.Sqrt(3) * voltaje * corriente * factorPotencia;
// 29,527 W ≈ 29.5 kW
Otras funciones útiles:
Math.Abs(-15.5); // Valor absoluto: 15.5
Math.Round(15.678); // Redondeo: 16
Math.Round(15.678, 2); // Redondeo 2 decimales: 15.68
Math.Ceiling(15.1); // Redondeo hacia arriba: 16
Math.Floor(15.9); // Redondeo hacia abajo: 15
Math.Max(10, 20); // Máximo: 20
Math.Min(10, 20); // Mínimo: 10
3. Operadores de comparación
Comparan dos valores y devuelven un bool (true o false).
| Operador | Significado | Ejemplo | Resultado |
|---|---|---|---|
== | Igual a | 5 == 5 | true |
!= | Diferente de | 5 != 3 | true |
> | Mayor que | 10 > 5 | true |
< | Menor que | 10 < 5 | false |
>= | Mayor o igual | 10 >= 10 | true |
<= | Menor o igual | 10 <= 5 | false |
Ejemplos prácticos:
double voltajeMedido = 235.5;
double voltajeNominal = 230.0;
bool voltajeMayor = voltajeMedido > voltajeNominal; // true
bool voltajeIgual = voltajeMedido == voltajeNominal; // false
bool volajeDiferente = voltajeMedido != voltajeNominal; // true
Uso típico: Verificar límites
double corriente = 18.5;
double corrienteMaxima = 16.0;
bool excedeLimite = corriente > corrienteMaxima; // true
if (excedeLimite)
{
MessageBox.Show("¡ADVERTENCIA! Corriente excede el límite.");
}
Importante con double: No uses == para comparar decimales
double a = 0.1 + 0.2; // 0.30000000000000004
double b = 0.3;
bool sonIguales = (a == b); // Puede ser false debido a precisión
// Mejor: compara con tolerancia
double tolerancia = 0.0001;
bool sonIgualesAprox = Math.Abs(a - b) < tolerancia; // true
4. Operadores lógicos
Combinan múltiples condiciones booleanas.
4.1 AND lógico (&&) - "Y"
true solo si ambas condiciones son verdaderas.
bool condicion1 = true;
bool condicion2 = true;
bool resultado = condicion1 && condicion2; // true
Tabla de verdad:
| A | B | A && B |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
Ejemplo práctico: Verificar rango de voltaje
double voltaje = 235.0;
double minimo = 207.0; // 230V - 10%
double maximo = 253.0; // 230V + 10%
bool dentroRango = (voltaje >= minimo) && (voltaje <= maximo); // true
Otro ejemplo: Validar circuito completo
double corriente = 15.5;
double corrienteMaxima = 16.0;
double caidaTension = 5.2;
double caidaMaxima = 6.9; // 3% de 230V
bool circuitoOK = (corriente <= corrienteMaxima) && (caidaTension <= caidaMaxima);
// true (ambas condiciones se cumplen)
4.2 OR lógico (||) - "O"
true si al menos una condición es verdadera.
bool condicion1 = true;
bool condicion2 = false;
bool resultado = condicion1 || condicion2; // true
Tabla de verdad:
| A | B | A || B |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
Ejemplo práctico: Detectar situaciones anormales
double voltaje = 195.0;
double corriente = 18.5;
bool voltajeBajo = voltaje < 207.0;
bool corrienteAlta = corriente > 16.0;
bool requiereAtencion = voltajeBajo || corrienteAlta; // true
// (cualquiera de las dos condiciones anormales activa la alerta)
4.3 NOT lógico (!) - "NO"
Invierte el valor booleano.
bool proyectoAbierto = true;
bool proyectoCerrado = !proyectoAbierto; // false
Ejemplos prácticos:
bool tieneErrores = false;
bool estaLimpio = !tieneErrores; // true
bool esTrifasico = true;
bool esMonofasico = !esTrifasico; // false
Uso común: Verificar negaciones
bool backupRealizado = false;
if (!backupRealizado)
{
MessageBox.Show("Advertencia: No se ha realizado backup.");
}
4.4 Combinando operadores lógicos
Puedes combinar múltiples operadores:
double voltaje = 235.0;
double corriente = 15.0;
double temperatura = 45.0;
bool voltajeOK = (voltaje >= 207.0) && (voltaje <= 253.0);
bool corrienteOK = corriente <= 16.0;
bool temperaturaOK = temperatura <= 50.0;
bool sistemaOK = voltajeOK && corrienteOK && temperaturaOK; // true
Con OR y AND:
// Alerta si: voltaje fuera de rango O corriente alta
bool alerta = (voltaje < 207.0 || voltaje > 253.0) || (corriente > 16.0);
5. Precedencia de operadores
Cuando combinas múltiples operadores, C# los evalúa en un orden específico.
5.1 Orden de precedencia (de mayor a menor)
- Paréntesis
( ) - Incremento/Decremento
++,-- - Unarios
!,-(negación) - Multiplicación, División, Módulo
*,/,% - Suma, Resta
+,- - Comparación
<,>,<=,>= - Igualdad
==,!= - AND lógico
&& - OR lógico
|| - Asignación
=,+=,-=, etc.
5.2 Ejemplos de precedencia
int resultado = 5 + 3 * 2; // 11, no 16
// Porque * tiene mayor precedencia que +
// Equivale a: 5 + (3 * 2)
int resultado = (5 + 3) * 2; // 16
// Los paréntesis fuerzan el orden
Con operadores lógicos:
bool resultado = true || false && false; // true
// && tiene mayor precedencia que ||
// Equivale a: true || (false && false)
// Equivale a: true || false
// Resultado: true
bool resultado = (true || false) && false; // false
// Paréntesis cambian el orden
5.3 Buenas prácticas
Siempre usa paréntesis cuando tengas dudas o cuando mejore la legibilidad:
// Poco claro
bool ok = voltaje > 207 && voltaje < 253 || corriente < 16;
// Claro con paréntesis
bool ok = ((voltaje > 207) && (voltaje < 253)) || (corriente < 16);
Ejemplo práctico bien estructurado:
double voltaje = 235.0;
double corriente = 15.5;
double caidaTension = 5.0;
bool voltajeDentroRango = (voltaje >= 207.0) && (voltaje <= 253.0);
bool corrienteSegura = (corriente <= 16.0);
bool caidaTensionAceptable = (caidaTension <= 6.9);
bool instalacionCorrecta = voltajeDentroRango && corrienteSegura && caidaTensionAceptable;
Este estilo:
- Es fácil de leer
- Es fácil de depurar
- Es fácil de modificar
6. Expresiones complejas en ingeniería eléctrica
Veamos cómo construir expresiones reales que usarías en proyectos.
6.1 Verificar rango de voltaje (±10%)
double voltajeNominal = 230.0;
double voltajeMedido = 235.5;
double tolerancia = 0.10; // 10%
double minimo = voltajeNominal * (1 - tolerancia); // 207V
double maximo = voltajeNominal * (1 + tolerancia); // 253V
bool voltajeOK = (voltajeMedido >= minimo) && (voltajeMedido <= maximo);
6.2 Calcular y validar caída de tensión
// Datos del cable
double longitudMetros = 50.0;
double corrienteAmperios = 16.0;
double seccionMM2 = 2.5;
double resistividadCobre = 0.018;
// Cálculo de caída de tensión
double caidaTension = (2 * longitudMetros * corrienteAmperios * resistividadCobre) / seccionMM2;
// Validar contra límite del 3%
double voltajeNominal = 230.0;
double caidaMaximaPermitida = voltajeNominal * 0.03; // 6.9V
bool caidaAceptable = caidaTension <= caidaMaximaPermitida;
double porcentajeCaida = (caidaTension / voltajeNominal) * 100;
6.3 Dimensionar cable por corriente admisible
double corrienteCircuito = 32.0; // A
double factorTemperatura = 0.94;
double factorAgrupacion = 0.80;
// Corriente corregida que debe soportar el cable
double corrienteCorregida = corrienteCircuito / (factorTemperatura * factorAgrupacion);
// ¿Cable de 6mm² (43A) es suficiente?
double corrienteAdmisible6mm = 43.0;
bool cable6mmSuficiente = corrienteAdmisible6mm >= corrienteCorregida;
// ¿Cable de 4mm² (36A) es suficiente?
double corrienteAdmisible4mm = 36.0;
bool cable4mmSuficiente = corrienteAdmisible4mm >= corrienteCorregida;
6.4 Factor de potencia y potencia reactiva
double potenciaActiva = 15000.0; // W
double factorPotencia = 0.75;
// Calcular potencia aparente: S = P / cos φ
double potenciaAparente = potenciaActiva / factorPotencia; // 20000 VA
// Calcular potencia reactiva: Q = √(S² - P²)
double potenciaReactiva = Math.Sqrt(
Math.Pow(potenciaAparente, 2) - Math.Pow(potenciaActiva, 2)
); // 13229 VAr
// ¿Factor de potencia aceptable? (mínimo 0.92)
bool fpAceptable = factorPotencia >= 0.92;
// Capacitor necesario para corregir a 0.92
double factorPotenciaObjetivo = 0.92;
double anguloActual = Math.Acos(factorPotencia);
double anguloObjetivo = Math.Acos(factorPotenciaObjetivo);
double potenciaCapacitor = potenciaActiva * (Math.Tan(anguloActual) - Math.Tan(anguloObjetivo));
Manos a la obra: Construyendo el proyecto
Vamos a crear un Sistema de Verificación de Instalación Eléctrica que valida múltiples parámetros.
Paso 1: Estructura básica y datos de entrada
using System;
using Eplan.EplApi.Base;
using Eplan.EplApi.ApplicationFramework;
public class VerificacionInstalacion
{
[Start]
public void Ejecutar()
{
// ========================================
// DATOS DE LA INSTALACIÓN
// ========================================
string nombreCircuito = "Circuito Taller - Línea 3";
// Parámetros eléctricos medidos
double voltajeMedido = 225.0; // V
double corrienteMedida = 14.8; // A
double factorPotencia = 0.88;
// Datos del cable instalado
double longitudCable = 45.0; // m
double seccionCable = 2.5; // mm²
double corrienteAdmisible = 21.0; // A (tabla para 2.5mm²)
// Límites normativos
double voltajeNominal = 230.0; // V
double corrienteCircuito = 16.0; // A (protección)
double toleranciaVoltaje = 0.10; // 10%
double caidaMaximaPorcentaje = 0.03; // 3%
double factorPotenciaMinimo = 0.85;
}
}
¿Qué acabamos de hacer? Definimos todos los parámetros que vamos a verificar en una instalación real.
Paso 2: Verificación de voltaje
// ========================================
// VERIFICACIÓN 1: RANGO DE VOLTAJE
// ========================================
double voltajeMinimo = voltajeNominal * (1 - toleranciaVoltaje);
double voltajeMaximo = voltajeNominal * (1 + toleranciaVoltaje);
bool voltajeOK = (voltajeMedido >= voltajeMinimo) && (voltajeMedido <= voltajeMaximo);
string resultadoVoltaje;
if (voltajeOK)
{
resultadoVoltaje = string.Format("OK ({0:F1}V está entre {1:F1}V y {2:F1}V)",
voltajeMedido, voltajeMinimo, voltajeMaximo);
}
else
{
resultadoVoltaje = string.Format("FALLO ({0:F1}V fuera del rango {1:F1}V - {2:F1}V)",
voltajeMedido, voltajeMinimo, voltajeMaximo);
}
¿Qué acabamos de hacer? Verificamos que el voltaje medido esté dentro del rango ±10% del nominal.
Paso 3: Verificación de corriente
// ========================================
// VERIFICACIÓN 2: CORRIENTE
// ========================================
bool corrienteOK = (corrienteMedida <= corrienteCircuito);
string resultadoCorriente;
if (corrienteOK)
{
double porcentajeUso = (corrienteMedida / corrienteCircuito) * 100;
resultadoCorriente = string.Format("OK ({0:F1}A / {1:F1}A = {2:F1}% de uso)",
corrienteMedida, corrienteCircuito, porcentajeUso);
}
else
{
resultadoCorriente = string.Format("FALLO ({0:F1}A excede límite de {1:F1}A)",
corrienteMedida, corrienteCircuito);
}
Paso 4: Cálculo y verificación de caída de tensión
// ========================================
// VERIFICACIÓN 3: CAÍDA DE TENSIÓN
// ========================================
double resistividadCobre = 0.018; // Ω·mm²/m
double caidaTension = (2 * longitudCable * corrienteMedida * resistividadCobre) / seccionCable;
double porcentajeCaida = (caidaTension / voltajeNominal) * 100;
double caidaMaximaVoltios = voltajeNominal * caidaMaximaPorcentaje;
bool caidaTensionOK = (caidaTension <= caidaMaximaVoltios);
string resultadoCaida;
if (caidaTensionOK)
{
resultadoCaida = string.Format("OK ({0:F2}V = {1:F2}% < {2:F2}%)",
caidaTension, porcentajeCaida, caidaMaximaPorcentaje * 100);
}
else
{
resultadoCaida = string.Format("FALLO ({0:F2}V = {1:F2}% > {2:F2}%)",
caidaTension, porcentajeCaida, caidaMaximaPorcentaje * 100);
}
¿Qué acabamos de hacer? Calculamos la caída de tensión en el cable y verificamos que esté bajo el 3%.
Paso 5: Verificación de factor de potencia
// ========================================
// VERIFICACIÓN 4: FACTOR DE POTENCIA
// ========================================
bool factorPotenciaOK = (factorPotencia >= factorPotenciaMinimo);
string resultadoFP;
if (factorPotenciaOK)
{
resultadoFP = string.Format("OK ({0:F2} >= {1:F2})",
factorPotencia, factorPotenciaMinimo);
}
else
{
resultadoFP = string.Format("BAJO ({0:F2} < {1:F2})",
factorPotencia, factorPotenciaMinimo);
}
Paso 6: Verificación de dimensionado de cable
// ========================================
// VERIFICACIÓN 5: DIMENSIONADO CABLE
// ========================================
bool cableDimensionadoOK = (corrienteAdmisible >= corrienteMedida);
string resultadoCable;
if (cableDimensionadoOK)
{
double margenSeguridad = ((corrienteAdmisible - corrienteMedida) / corrienteAdmisible) * 100;
resultadoCable = string.Format("OK ({0}mm² soporta {1:F1}A, medido {2:F1}A, margen {3:F1}%)",
seccionCable, corrienteAdmisible, corrienteMedida, margenSeguridad);
}
else
{
resultadoCable = string.Format("FALLO ({0}mm² solo soporta {1:F1}A, medido {2:F1}A)",
seccionCable, corrienteAdmisible, corrienteMedida);
}
Paso 7: Evaluación general y construcción del mensaje
// ========================================
// EVALUACIÓN GENERAL
// ========================================
bool instalacionConforme = voltajeOK && corrienteOK && caidaTensionOK &&
factorPotenciaOK && cableDimensionadoOK;
string estadoGeneral = instalacionConforme ? "CONFORME" : "NO CONFORME";
// ========================================
// CONSTRUCCIÓN DEL REPORTE
// ========================================
string reporte = string.Format(
"=== VERIFICACIÓN DE INSTALACIÓN ELÉCTRICA ===\n\n" +
"Circuito: {0}\n" +
"Estado: {1}\n\n" +
"RESULTADOS:\n\n" +
"1. Voltaje: {2}\n" +
"2. Corriente: {3}\n" +
"3. Caída tensión: {4}\n" +
"4. Factor potencia: {5}\n" +
"5. Dimensionado cable: {6}\n\n" +
"DATOS TÉCNICOS:\n" +
"- Cable: {7}mm², {8}m\n" +
"- Potencia activa: {9:F2} W\n" +
"- Potencia aparente: {10:F2} VA",
nombreCircuito,
estadoGeneral,
resultadoVoltaje,
resultadoCorriente,
resultadoCaida,
resultadoFP,
resultadoCable,
seccionCable,
longitudCable,
voltajeMedido * corrienteMedida * factorPotencia,
voltajeMedido * corrienteMedida
);
// ========================================
// MOSTRAR REPORTE
// ========================================
MessageBoxIcon icono = instalacionConforme ? MessageBoxIcon.Information : MessageBoxIcon.Warning;
MessageBox.Show(reporte, "Verificación de Instalación", MessageBoxButtons.OK, icono);
¿Qué acabamos de hacer? Combinamos todos los resultados en un reporte completo y mostramos un icono diferente según el resultado.
Código completo del proyecto
using System;
using Eplan.EplApi.Base;
using Eplan.EplApi.ApplicationFramework;
public class VerificacionInstalacion
{
[Start]
public void Ejecutar()
{
// ========================================
// DATOS DE LA INSTALACIÓN
// ========================================
string nombreCircuito = "Circuito Taller - Línea 3";
// Parámetros eléctricos medidos
double voltajeMedido = 225.0; // V
double corrienteMedida = 14.8; // A
double factorPotencia = 0.88;
// Datos del cable instalado
double longitudCable = 45.0; // m
double seccionCable = 2.5; // mm²
double corrienteAdmisible = 21.0; // A (tabla para 2.5mm²)
// Límites normativos
double voltajeNominal = 230.0; // V
double corrienteCircuito = 16.0; // A (protección)
double toleranciaVoltaje = 0.10; // 10%
double caidaMaximaPorcentaje = 0.03; // 3%
double factorPotenciaMinimo = 0.85;
// ========================================
// VERIFICACIÓN 1: RANGO DE VOLTAJE
// ========================================
double voltajeMinimo = voltajeNominal * (1 - toleranciaVoltaje);
double voltajeMaximo = voltajeNominal * (1 + toleranciaVoltaje);
bool voltajeOK = (voltajeMedido >= voltajeMinimo) && (voltajeMedido <= voltajeMaximo);
string resultadoVoltaje;
if (voltajeOK)
{
resultadoVoltaje = string.Format("OK ({0:F1}V está entre {1:F1}V y {2:F1}V)",
voltajeMedido, voltajeMinimo, voltajeMaximo);
}
else
{
resultadoVoltaje = string.Format("FALLO ({0:F1}V fuera del rango {1:F1}V - {2:F1}V)",
voltajeMedido, voltajeMinimo, voltajeMaximo);
}
// ========================================
// VERIFICACIÓN 2: CORRIENTE
// ========================================
bool corrienteOK = (corrienteMedida <= corrienteCircuito);
string resultadoCorriente;
if (corrienteOK)
{
double porcentajeUso = (corrienteMedida / corrienteCircuito) * 100;
resultadoCorriente = string.Format("OK ({0:F1}A / {1:F1}A = {2:F1}% de uso)",
corrienteMedida, corrienteCircuito, porcentajeUso);
}
else
{
resultadoCorriente = string.Format("FALLO ({0:F1}A excede límite de {1:F1}A)",
corrienteMedida, corrienteCircuito);
}
// ========================================
// VERIFICACIÓN 3: CAÍDA DE TENSIÓN
// ========================================
double resistividadCobre = 0.018; // Ω·mm²/m
double caidaTension = (2 * longitudCable * corrienteMedida * resistividadCobre) / seccionCable;
double porcentajeCaida = (caidaTension / voltajeNominal) * 100;
double caidaMaximaVoltios = voltajeNominal * caidaMaximaPorcentaje;
bool caidaTensionOK = (caidaTension <= caidaMaximaVoltios);
string resultadoCaida;
if (caidaTensionOK)
{
resultadoCaida = string.Format("OK ({0:F2}V = {1:F2}% < {2:F2}%)",
caidaTension, porcentajeCaida, caidaMaximaPorcentaje * 100);
}
else
{
resultadoCaida = string.Format("FALLO ({0:F2}V = {1:F2}% > {2:F2}%)",
caidaTension, porcentajeCaida, caidaMaximaPorcentaje * 100);
}
// ========================================
// VERIFICACIÓN 4: FACTOR DE POTENCIA
// ========================================
bool factorPotenciaOK = (factorPotencia >= factorPotenciaMinimo);
string resultadoFP;
if (factorPotenciaOK)
{
resultadoFP = string.Format("OK ({0:F2} >= {1:F2})",
factorPotencia, factorPotenciaMinimo);
}
else
{
resultadoFP = string.Format("BAJO ({0:F2} < {1:F2})",
factorPotencia, factorPotenciaMinimo);
}
// ========================================
// VERIFICACIÓN 5: DIMENSIONADO CABLE
// ========================================
bool cableDimensionadoOK = (corrienteAdmisible >= corrienteMedida);
string resultadoCable;
if (cableDimensionadoOK)
{
double margenSeguridad = ((corrienteAdmisible - corrienteMedida) / corrienteAdmisible) * 100;
resultadoCable = string.Format("OK ({0}mm² soporta {1:F1}A, medido {2:F1}A, margen {3:F1}%)",
seccionCable, corrienteAdmisible, corrienteMedida, margenSeguridad);
}
else
{
resultadoCable = string.Format("FALLO ({0}mm² solo soporta {1:F1}A, medido {2:F1}A)",
seccionCable, corrienteAdmisible, corrienteMedida);
}
// ========================================
// EVALUACIÓN GENERAL
// ========================================
bool instalacionConforme = voltajeOK && corrienteOK && caidaTensionOK &&
factorPotenciaOK && cableDimensionadoOK;
string estadoGeneral = instalacionConforme ? "CONFORME" : "NO CONFORME";
// ========================================
// CONSTRUCCIÓN DEL REPORTE
// ========================================
string reporte = string.Format(
"=== VERIFICACIÓN DE INSTALACIÓN ELÉCTRICA ===\n\n" +
"Circuito: {0}\n" +
"Estado: {1}\n\n" +
"RESULTADOS:\n\n" +
"1. Voltaje: {2}\n" +
"2. Corriente: {3}\n" +
"3. Caída tensión: {4}\n" +
"4. Factor potencia: {5}\n" +
"5. Dimensionado cable: {6}\n\n" +
"DATOS TÉCNICOS:\n" +
"- Cable: {7}mm², {8}m\n" +
"- Potencia activa: {9:F2} W\n" +
"- Potencia aparente: {10:F2} VA",
nombreCircuito,
estadoGeneral,
resultadoVoltaje,
resultadoCorriente,
resultadoCaida,
resultadoFP,
resultadoCable,
seccionCable,
longitudCable,
voltajeMedido * corrienteMedida * factorPotencia,
voltajeMedido * corrienteMedida
);
// ========================================
// MOSTRAR REPORTE
// ========================================
MessageBoxIcon icono = instalacionConforme ? MessageBoxIcon.Information : MessageBoxIcon.Warning;
MessageBox.Show(reporte, "Verificación de Instalación", MessageBoxButtons.OK, icono);
}
}
Deep Dive: Entendiendo en profundidad
Evaluación de cortocircuito (short-circuit evaluation)
Los operadores && y || son "perezosos": si el resultado ya es obvio, no evalúan el resto.
Con AND (&&):
bool a = false;
bool b = ExpresionCompleja(); // Esta función NO se ejecutará
bool resultado = a && b; // false (porque a ya es false)
Si a es false, el resultado siempre será false, así que C# no evalúa b.
Con OR (||):
bool a = true;
bool b = ExpresionCompleja(); // Esta función NO se ejecutará
bool resultado = a || b; // true (porque a ya es true)
Uso práctico: Evitar errores de división por cero
double divisor = 0;
double dividendo = 10;
// Peligroso: siempre divide, puede dar error
if (dividendo / divisor > 5) { } // ERROR: divide por cero
// Seguro: solo divide si divisor != 0
if (divisor != 0 && (dividendo / divisor > 5))
{
// Solo entra aquí si divisor != 0
}
Operadores bit a bit
Para manipulación de bits (poco común en EPLAN, pero útil para flags):
int a = 5; // 0101 en binario
int b = 3; // 0011 en binario
int andBit = a & b; // 0001 = 1
int orBit = a | b; // 0111 = 7
int xorBit = a ^ b; // 0110 = 6
int notBit = ~a; // 1010 (invertido)
Uso práctico: Trabajar con flags de EPLAN (lo veremos en capítulos avanzados).
Operador de coalescencia nula (??)
Para valores que pueden ser null:
string nombreProyecto = ObtenerNombre(); // Puede devolver null
string nombreFinal = nombreProyecto ?? "Sin nombre";
// Si nombreProyecto es null, usa "Sin nombre"
Equivalente a:
string nombreFinal;
if (nombreProyecto != null)
{
nombreFinal = nombreProyecto;
}
else
{
nombreFinal = "Sin nombre";
}
Mejores prácticas con expresiones
1. Divide expresiones complejas en pasos
// Mal: difícil de leer y depurar
bool ok = (v >= vMin && v <= vMax) && (i <= iMax) && ((2*l*i*r)/s <= vMax*0.03);
// Bien: cada verificación es clara
bool voltajeOK = (voltaje >= voltajeMinimo) && (voltaje <= voltajeMaximo);
bool corrienteOK = (corriente <= corrienteMaxima);
double caidaTension = (2 * longitud * corriente * resistividad) / seccion;
bool caidaOK = (caidaTension <= voltajeMaximo * 0.03);
bool todoOK = voltajeOK && corrienteOK && caidaOK;
2. Usa variables intermedias con nombres descriptivos
// Mal
double x = (v * i * 1.732 * 0.85) / 1000;
// Bien
double voltaje = 400.0;
double corriente = 50.0;
double raizDeTres = 1.732;
double factorPotencia = 0.85;
double potenciaKW = (voltaje * corriente * raizDeTres * factorPotencia) / 1000;
// O mejor aún:
double potenciaKW = (voltaje * corriente * Math.Sqrt(3) * factorPotencia) / 1000;
3. Comenta fórmulas complejas
// Sección mínima de cable según ITC-BT-19
// S = (2 * L * I) / (γ * ΔU)
// donde: γ = conductividad (56 m/Ω·mm² para Cu)
// ΔU = caída de tensión admisible
double seccionMinima = (2 * longitudMetros * corrienteAmperios) /
(56 * caidaTensionAdmisible);
Errores comunes
Error 1: Confundir = con ==
Síntoma: Asignación en lugar de comparación.
int voltaje = 230;
if (voltaje = 400) // ERROR: asignación, no comparación
{
// Este bloque siempre se ejecuta
}
Solución:
if (voltaje == 400) // Comparación correcta
{
// Solo entra si voltaje es 400
}
Error 2: Olvidar paréntesis en expresiones mixtas
Síntoma: Resultado inesperado por precedencia.
bool ok = voltaje > 207 && voltaje < 253 || corriente < 16;
// ¿Qué se evalúa primero?
Solución: Usa paréntesis
bool ok = ((voltaje > 207) && (voltaje < 253)) || (corriente < 16);
Error 3: División entera cuando esperas decimal
Ya lo vimos en el capítulo anterior, pero es tan común que vale la pena repetirlo:
int total = 100;
int partes = 3;
double resultado = total / partes; // 33.0, no 33.333...
Solución:
double resultado = (double)total / partes; // 33.333...
Desafíos (Opcional)
Desafío 1: Selector de cable automático
Dificultad: Media
Crea un script que dados:
- Corriente del circuito
- Longitud del cable
- Caída de tensión máxima permitida
Determine la sección mínima necesaria de cable y sugiera la sección normalizada más cercana (1.5, 2.5, 4, 6, 10, 16 mm²).
Pista
Usa la fórmula: S = (2 × L × I × ρ) / ΔV
Luego compara el resultado con cada sección normalizada hasta encontrar la primera que sea mayor o igual.
Desafío 2: Calculadora de corrección de factor de potencia
Dificultad: Alta
Crea un script que:
- Reciba: potencia activa, factor de potencia actual, factor de potencia objetivo
- Calcule: capacidad del banco de capacitores necesario (kVAr)
- Valide: que el factor de potencia objetivo sea mayor que el actual
Fórmulas:
- Qc = P × (tan(φ1) - tan(φ2))
- donde φ = acos(factor de potencia)
Pista
Usa Math.Acos() para obtener el ángulo a partir del factor de potencia, y Math.Tan() para la tangente.
Desafío 3: Verificador de cortocircuito
Dificultad: Alta
Calcula la corriente de cortocircuito en el extremo de un cable y verifica si el poder de corte del interruptor es suficiente.
Datos:
- Corriente de cortocircuito en el origen (Icc)
- Impedancia del cable: Z = (ρ × L) / S
- Icc en el extremo = V / Z_total
Valida que el interruptor tenga capacidad suficiente.
Recursos adicionales
Preguntas frecuentes
P: ¿Cuándo uso && y cuándo uso ||?
R: Usa && (AND) cuando todas las condiciones deben cumplirse. Usa || (OR) cuando al menos una debe cumplirse. Piensa: "Voltaje OK Y corriente OK" usa &&. "Voltaje fuera de rango O corriente excesiva" usa ||.
P: ¿Por qué a veces uso paréntesis en expresiones y a veces no?
R: Los paréntesis fuerzan el orden de evaluación y mejoran la legibilidad. Siempre úsalos cuando combines operadores diferentes (aritméticos con lógicos) o cuando tengas dudas sobre precedencia.
P: ¿Cuál es la diferencia entre i++ y ++i?
R: i++ (postfijo) devuelve el valor actual y luego incrementa. ++i (prefijo) incrementa primero y luego devuelve el nuevo valor. En la práctica, úsalos en líneas separadas y no habrá diferencia.
P: ¿Puedo comparar dos double con == ?
R: Técnicamente sí, pero no es recomendable por problemas de precisión de punto flotante. Es mejor comparar con una tolerancia: Math.Abs(a - b) < 0.0001.
P: ¿Qué pasa si divido por cero?
R: Con enteros, lanza una excepción (error). Con double, devuelve Infinity. Siempre valida que el divisor no sea cero antes de dividir.
Checklist de completitud
Antes de pasar al siguiente capítulo, asegúrate de:
- Entender todos los operadores aritméticos (incluyendo % y ++)
- Poder usar operadores de comparación para evaluar condiciones
- Saber combinar condiciones con &&, ||, y !
- Entender el orden de precedencia de operadores
- Haber ejecutado exitosamente el script de verificación
- Poder construir expresiones complejas para cálculos eléctricos
- Saber dividir expresiones complejas en pasos más simples
- (Opcional) Haber intentado al menos un desafío
Última actualización: Enero 2025
Tiempo de lectura estimado: 45-50 minutos
Código de ejemplo: code/cap-04/