Ir al contenido

Capítulo 4: Operaciones y expresiones

Parte I - Sección 1: Fundamentos de C# - Nivel: Principiante


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

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

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


1. Introducción: De cálculos simples a expresiones complejas

Sección titulada «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

Ya conoces los básicos: +, -, *, /. Veamos operadores adicionales y técnicas útiles.

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)

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

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

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

Comparan dos valores y devuelven un bool (true o false).

OperadorSignificadoEjemploResultado
==Igual a5 == 5true
!=Diferente de5 != 3true
>Mayor que10 > 5true
<Menor que10 < 5false
>=Mayor o igual10 >= 10true
<=Menor o igual10 <= 5false

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

Combinan múltiples condiciones booleanas.

true solo si ambas condiciones son verdaderas.

bool condicion1 = true;
bool condicion2 = true;
bool resultado = condicion1 && condicion2; // true

Tabla de verdad:

ABA && B
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

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)

true si al menos una condición es verdadera.

bool condicion1 = true;
bool condicion2 = false;
bool resultado = condicion1 || condicion2; // true

Tabla de verdad:

ABA || B
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

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)

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.");
}

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

Cuando combinas múltiples operadores, C# los evalúa en un orden específico.

  1. Paréntesis ( )
  2. Incremento/Decremento ++, --
  3. Unarios !, - (negación)
  4. Multiplicación, División, Módulo *, /, %
  5. Suma, Resta +, -
  6. Comparación <, >, <=, >=
  7. Igualdad ==, !=
  8. AND lógico &&
  9. OR lógico ||
  10. Asignación =, +=, -=, etc.
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

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

Sección titulada «6. Expresiones complejas en ingeniería eléctrica»

Veamos cómo construir expresiones reales que usarías en proyectos.

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);
// 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

Sección titulada «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;
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));

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

Sección titulada «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.


// ========================================
// 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.


// ========================================
// 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

Sección titulada «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%.


// ========================================
// 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

Sección titulada «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

Sección titulada «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.


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

Evaluación de cortocircuito (short-circuit evaluation)

Sección titulada «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
}

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).

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

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

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

Sección titulada «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

Sección titulada «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...

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

Sección titulada «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.


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.



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?

Sección titulada «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?

Sección titulada «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.

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.

R: Con enteros, lanza una excepción (error). Con double, devuelve Infinity. Siempre valida que el divisor no sea cero antes de dividir.


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/