Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

18 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 2 de diciembre de 2008
Código fuenteAl escribir el post "Métodos genéricos en C#", estuve pensando en tratar este tema también en VB.NET de forma simultánea, pero al final preferí limitarme a C# para no hacer la entrada más extensa de lo que ya iba a resultar de por sí.

Esto, unido a un comentario de Julio sobre el propio post en el que preguntaba si existía algo parecido en Visual Basic .NET, ha hecho que reedite el mismo, pero centrándome esta vez en dicho lenguaje.

Los métodos genéricos son interesantes herramientas que están con nosotros desde los tiempos del .NET Framework 2.0 y pueden resultarnos muy útiles de cara a la construcción de frameworks o librerías reutilizables.

Podríamos considerar que un método genérico es a un método tradicional lo que una clase genérica a una tradicional; por tanto, se trata de un mecanismo de definición de métodos con tipos parametrizados, que nos ofrece la potencia del tipado fuerte en sus parámetros y devoluciones aun sin conocer los tipos concretos que utilizaremos al invocarlos.

Vamos a profundizar en el tema desarrollando un ejemplo, a través del cual podremos comprender por qué los métodos genéricos pueden sernos muy útiles para solucionar determinado tipo de problemas, y describiremos ciertos aspectos, como las restricciones o la inferencia, que nos ayudarán a sacarles mucho jugo.

Escenario de partida

Como sabemos, los métodos tradicionales trabajan con parámetros y retornos fuertemente tipados, es decir, en todo momento conocemos los tipos concretos de los argumentos que recibimos y de los valores que devolvemos. Por ejemplo, en el siguiente código, vemos que el método Maximo, cuya misión es obvia, recibe dos valores Integer y retorna un valor del mismo tipo:
  Function Maximo(ByVal uno As Integer, ByVal otro As Integer) _
As Integer
If uno > otro Then Return uno
Return otro
End Function
 
Hasta ahí, todo correcto. Sin embargo, está claro que retornar el máximo de dos valores es una operación que podría ser aplicada a más tipos, prácticamente a todos los que pudieran ser comparados. Si quisiéramos generalizar este método y hacerlo accesible para otros tipos, se nos podrían ocurrir al menos dos formas de hacerlo.

La primera sería realizar un buen puñado de sobrecargas del método para intentar cubrir todos los casos que se nos puedan dar:

Function Maximo(ByVal uno As Integer, ByVal otro As Integer) _
As Integer
' ...
End Function
Function Maximo(ByVal uno As Long, ByVal otro As Long) _
As Long
' ...
End Function
Function Maximo(ByVal uno As Decimal, ByVal otro As Decimal) _
As Decimal
' ...
End Function

' Y así hasta que te aburras...
 
Obviamente, sería un trabajo demasiado duro para nosotros, desarrolladores perezosos como somos. Además, según Murphy, por más sobrecargas que creáramos seguro que siempre nos faltaría al menos una: justo la que vamos a necesitar ;-).

Otra posibilidad sería intentar generalizar utilizando las propiedades de la herencia. Es decir, si asumimos que tanto los valores de entrada del método como su retorno son del tipo base Object, aparentemente tendríamos el tema resuelto. Lamentablemente, al finalizar nuestra implementación nos daríamos cuenta de que no es posible hacer comparaciones entre dos Object's, por lo que, o bien incluimos en el cuerpo del método código para comprobar que ambos sean comparables (consultando si implementan IComparable), o bien elevamos el listón de entrada a nuestro método, así:
  Function Maximo(ByVal uno As IComparable, ByVal otro As Object) As Object
If uno.CompareTo(otro) > 0 Then Return uno
Return otro
End Function
 
Pero efectivamente, como ya habréis notado, esto tampoco sería una solución válida para nuestro caso. En primer lugar, el hecho de que ambos parámetros sean Object o IComparable no asegura en ningún momento que sean del mismo tipo, por lo que podría invocar el método enviándole, por ejemplo, un String y un Integer, lo que provocaría un error en tiempo de ejecución. Y aunque es cierto que podríamos incluir código que comprobara que ambos tipos son compatibles, ¿no tendríais la sensación de estar llevando a tiempo de ejecución problemática de tipado que bien podría solucionarse en compilación?

El método genérico

Fijaos que lo que andamos buscando es simplemente alguna forma de representar en el código una idea conceptualmente tan sencilla como: "mi método va a recibir dos objetos de un tipo cualquiera T, que implemente IComparable, y va a retornar el que sea mayor de ellos". En este momento es cuando los métodos genéricos acuden en nuestro auxilio, permitiendo definir ese concepto como sigue:
  Function Maximo(Of T As IComparable) _
(ByVal uno As T, ByVal otro As T) As T
If uno.CompareTo(otro) > 0 Then Return uno
Return otro
End Function
 
En el código anterior, podemos distinguir una porción de código que aparece resaltada justo después del nombre del método, y antes de comenzar a definir sus parámetros. Es la forma de indicar que Maximo es un método genérico y operará sobre un tipo cualquiera al que llamaremos T, y mediante una restricción estamos indicando que deberá implementar obligatoriamenter el interfaz IComparable (más adelante trataremos esto en profundidad).

A continuación, podemos observar que los dos parámetros de entrada son del tipo T, así como el retorno de la función. Si no lo ves claro, sustituye mentalmente la letra T por Integer (por ejemplo) y seguro que mejora la cosa.

Lógicamente, estos métodos pueden presentar un número indeterminado de parámetros genéricos, como en el siguiente ejemplo. Observad que la palabra clave Of sólo se indica al principio:
  Function MiMetodo(Of T1, T2, TResult) _
(ByVal par1 As T1, ByVal par2 As T2) As TResult
 
Y una aclaración antes de continuar: lo de usar la letra T para identificar el tipo es pura convención, podríamos llamarlo de cualquier forma (por ejemplo Maximo(Of MiTipo)(ByVal uno as MiTipo, ByVal otro as MiTipo) As MiTipo), aunque ceñirse a las convenciones de codificación es normalmente una buena idea.

Restricciones en parámetros genéricos

Retomemos un momento el código de nuestro método genérico:
  Function Maximo(Of T As IComparable) _
(ByVal uno As T, ByVal otro As T) As T
If uno.CompareTo(otro) > 0 Then Return uno
Return otro
End Function
 
Antes había comentado que en este caso estabamos creando un método que podría actuar sobre cualquier tipo, aunque mediante una restricción forzábamos a que éste implementara, obligatoriamente, el interfaz IComparable, lo que nos permitiría realizar la operación de comparación que necesitamos.

Obviamente, las restricciones no son obligatorias; de hecho, sólo debemos utilizarlas cuando necesitemos limitar de alguna forma los tipos permitidos como parámetros genéricos, como en el ejemplo anterior. Está permitida la utilización de las siguientes reglas:
  • As Structure, indica que el argumento debe ser un tipo valor.
  • As Class, indica que T debe ser un tipo referencia.
  • As New, fuerza a que el tipo T disponga de un constructor público sin parámetros; es útil cuando desde dentro del método se pretende instanciar un objeto del mismo.
  • As nombredeclase, indica que el argumento debe heredar o ser de dicho tipo.
  • As nombredeinterfaz, el argumento deberá implementar el interfaz indicado.
  • As nombredetipogenérico, indica que el argumento al que se aplica debe ser igual o heredar del tipo, también argumento del método, indicado por nombredetipogenérico (observad en el siguiente ejemplo el parámetro T2).
Un último detalle relativo a esto: a un mismo parámetro se pueden aplicar varias restricciones, en cuyo caso se introducirán entre llaves ("{" y "}") separadas por comas, como aparece en el siguiente ejemplo:
  Function MiMetodo(Of T1 As {Class, IEnumerable}, _
T2 As {T1, New}, _
TResult As New) _
(ByVal par1 As T1, ByVal par2 As T2) As TResult
' ... Cuerpo del método
End Function
 

Uso de métodos genéricos

A estas alturas ya sabemos, más o menos, cómo se define un método genérico, pero nos falta aún conocer cómo podemos consumirlos, es decir, invocarlos desde nuestras aplicaciones. Aunque puede intuirse, la llamada a los métodos genéricos debe incluir tanto la tradicional lista de parámetros del método como los tipos que lo concretan. Vemos unos ejemplos:
  Dim mazinger As String = Maximo(Of String)("Mazinger", "Afrodita")
Dim i99 As Integer = Maximo(Of Integer)(2, 99)
 
Una interesantísima característica de la invocación de estos métodos es la capacidad del compilador para inferir, en muchos casos, los tipos que debe utilizar como parámetros genéricos, evitándonos tener que indicarlos de forma expresa. El siguiente código, totalmente equivalente al anterior, aprovecha esta característica:
  Dim mazinger As String = Maximo("Mazinger", "Afrodita")
Dim i99 As Integer = Maximo(2, 99)
 
El compilador deduce el tipo del método genérico a partir de los que estamos utilizando en la lista de parámetros. Por ejemplo, en el primer caso, dado que los dos parámetros son String, puede llegar a la conclusión de que el método tiene una signatura que coincide con la definición del genérico, utilizando String como tipo parametrizado.

Otro ejemplo de método genérico

Veamos un ejemplo un poco más complejo. El método CreaLista, aplicable a cualquier clase, retorna una lista genérica (List(Of T)) del tipo parametrizado del método, que rellena inicialmente con los argumentos (variables) que se le suministra:
  Function CreaLista(Of T)(ByVal ParamArray pars() As T) As List(Of T)
Dim list As New List(Of T)
For Each elem As T In pars
list.Add(elem)
Next
Return list
End Function

' ...
' Uso:

Dim nums = CreaLista(Of Integer)(1, 2, 3, 4, 5, 6, 7)
Dim noms = CreaLista(Of String)("Pepe", "Juan", "Luis")
 
Otros ejemplos de uso, ahora beneficiándonos de la inferencia de tipos:
  Dim nums = CreaLista(1, 2, 3, 4, 5, 6, 7)
Dim noms = CreaLista("Pepe", "Juan", "Luis")

' Incluso con tipos anónimos de VB.NET 9
Dim v = CreaLista( _
New With {.X = 1, .Y = 2}, _
New With {.X = 3, .Y = 4} _
)
Console.WriteLine(v(1).Y) ' Muestra "4"
 
En resumen, se trata de una característica de la plataforma .NET, reflejada en lenguajes como C# y VB.Net, que está siendo ampliamente utilizada en las últimas incorporaciones al framework, y a la que hay que habituarse para poder trabajar eficientemente con ellas.

Publicado en: www.variablenotfound.com.
domingo, 30 de noviembre de 2008
Es habitual que las aplicaciones que desarrollamos necesiten enviar emails: alertas, notificaciones automáticas, formularios de contacto, o envíos masivos de información, entre otros, son ejemplos de utilización muy habituales.

Y en estos casos la inclusión de imágenes incrustadas suele ser un requisito fundamental cuando se trata de enviar contenidos con formato HTML, de forma que, aunque normalmente se incrementa de forma notable el tamaño del paquete a enviar, se evita que los clientes tengan que descargar estos recursos adicionales desde sus equipos, cosa que además suele estar bloqueada por defecto.

.NET framework nos ofrece varias vías para hacerlo usando las clases provistas en System.Net.Mail, pero vamos a utilizar una que nos ofrece dos ventajas importantes. La primera es que las imágenes enviadas no se muestran como adjuntos (evitando, por ejemplo, el curioso efecto presente en Outlook Express, que repite las imágenes a continuación del texto del mensaje) y la segunda es que permite especificar distintas vistas dentro desde el mismo mensaje, para que el cliente de correo utilice la que sea más apropiada.

El siguiente código muestra una forma de montar un mensaje con dos vistas: la primera será utilizada por aquellos agentes de usuario (clientes de correo) que únicamente pueden mostrar texto plano, mientras que en la segunda utilizará HTML para maquetar el contenido, incluyendo una imagen que aparecerá totalmente integrada en el cuerpo del mensaje, sin mostrarse como elemento adjunto del mismo.

Podréis observar que aunque en el ejemplo muestro un código muy rígido, es fácilmente generalizable para poder utilizarlo en cualquier escenario. Como en otras ocasiones, está en C#, mi lenguaje favorito, pero sería fácilmente portable a VB.NET, por ejemplo.

// Necesitaremos estos namespaces...
using System.Net.Mail;
using System.Net.Mime;
...

// Montamos la estructura básica del mensaje...
MailMessage mail = new MailMessage();
mail.From = new MailAddress("origen@miservidor.com");
mail.To.Add("destinatario@miservidor.com");
mail.Subject = "Mensaje con imagen";

// Creamos la vista para clientes que
// sólo pueden acceder a texto plano...


string text = "Hola, ayer estuve disfrutando de "+
"un paisaje estupendo.";

AlternateView plainView =
AlternateView.CreateAlternateViewFromString(text,
Encoding.UTF8,
MediaTypeNames.Text.Plain);


// Ahora creamos la vista para clientes que
// pueden mostrar contenido HTML...


string html = "<h2>Hola, mira dónde estuve ayer:</h2>" +
"<img src='cid:imagen' />";

AlternateView htmlView =
AlternateView.CreateAlternateViewFromString(html,
Encoding.UTF8,
MediaTypeNames.Text.Html);

// Creamos el recurso a incrustar. Observad
// que el ID que le asignamos (arbitrario) está
// referenciado desde el código HTML como origen
// de la imagen (resaltado en amarillo)...


LinkedResource img =
new LinkedResource(@"C:\paisaje.jpg",
MediaTypeNames.Image.Jpeg);
img.ContentId = "imagen";

// Lo incrustamos en la vista HTML...

htmlView.LinkedResources.Add(img);

// Por último, vinculamos ambas vistas al mensaje...

mail.AlternateViews.Add(plainView);
mail.AlternateViews.Add(htmlView);

// Y lo enviamos a través del servidor SMTP...

SmtpClient smtp = new SmtpClient("smtp.miservidor.com");
smtp.Send(mail);
 

La siguiente imagen muestra una captura de pantalla del mismo mensaje leído desde un cliente con capacidad HTML como Outlook Express y uno que no la tiene, en este caso basado en web:

El mismo mensaje visto desde dos agentes de usuario distintos. Pulsa para ampliar.


Publicado en: www.variablenotfound.com.
domingo, 23 de noviembre de 2008
Este artículo es una traducción del original "20 Famous Software Disasters - Part 4" publicado hace unos meses por Timm Martin en su blog Devtopics, realizada con permiso expreso de su autor.

Aquí puedes encontrar la primera, segunda y tercera parte.



Explosión de las Dot-bomb

16. El desplome de las Punto-Bomb (2000)

Coste: 5 billones de dólares en valores, fracaso de miles de compañías.

Desastre: la burbuja especulativa creada entre 1995 y 2001 alimentó un rápido aumento en inversiones en capital riesgo y valores bursátiles en Internet y los sectores tecnológicos. La burbuja "punto com" comenzó a hundirse al principio del 2000, eliminando billones en valores, miles de compañías y empleos, y comenzando una recesión global.

Causa: Las compañías e inversores obviaron los modelos de negocio habituales, centrándose en cambio en el aumento de cuota de mercado a expensas de los beneficios. (Más información)

El amor duele

17. El virus del amor (2000)

Coste: 8.750 millones de dólares, millones de ordenadores infectados, importantes pérdidas de información.

Desastre: El gusano LoveLetter (carta de amor) infectó millones de ordenadores y causó más daño que cualquier otro virus informático en la historia. El gusano eliminaba archivos, modificaba la página de inicio de los usuarios y el registro de Windows.

Causa: LoveLetter infectaba a los usuarios vía email, chats y carpetas compartidas. Enviaba a través de correo electrónico un mensaje con el asunto "ILOVEYOU" y un archivo adjunto; cuando el usuario abría el archivo, el virus infectaba su ordenador y se autoenviaba a todos los contactos de la libreta de direcciones. (Más información)

Zombies

18. Tratamiento contra el cáncer mortal (2000)

Coste: 8 personas muertas, 20 heridas de gravedad.

Desastre: El software de radiación terapéutica creado por Multidata Systems International fallaba al calcular la dosis apropiada, exponiendo a los pacientes a peligrosos, y en algunos casos mortales, niveles de radiación. Los físicos, a los que legalmente se exige una doble comprobación de los cálculos del software, fueron acusados de asesinato.

Causa: El software calculaba la dosis de radiación basándose en el orden en que los datos eran introducidos, lo que provocaba que a veces generara una dosis doble de radiación. (Más información)

Oliver Twist

19. EDS frena la ayuda al niño (2004)

Coste: 539 millones de libras, y sumando.

Desastre: El gigante de servicios EDS desarrolló un sistema informático para la agencia británica "Child Support Agency (CSA)" que accidentalmente pagó más de lo debido a 1.900.000 personas, pagó de menos a otras 700.000, tenía 3.500 millones de libras de manutención de niños sin cobrar, un atraso de 239.000 casos, 36.000 nuevos casos bloqueados en el sistema, y todavía hay más de 500 bugs documentados.

Causa: EDS introdujo un enorme y complejo sistema de información en la CSA de forma simultánea a una reestructuración de la agencia. (Más información)

X-Files

20. El final de la trilogía FBI (2005)

Coste: 105 millones de dólares, aún sin disponer de una solución de archivo efectiva.

Desastre: El FBI desechó su nuevo sistema informático después de cuatro años de esfuerzo. El macro-proyecto Trilogy, era un archivo virtual integrado que permitiría a los agentes compartir expedientes de casos y otra información.

Causa: La mala gestión, y un intento de construir un proyecto a largo plazo sobre tecnología que era obsoleta antes de que el proyecto se completara, resultando en un sistema complejo e inutilizable. (Más información)

Los desastres continúan

Aquí hay otros artículos más sobre desastres provocados por el software (en inglés):

Publicado en: www.variablenotfound.com.
Este artículo es una traducción del original "20 Famous Software Disasters - Part 3" publicado hace unos meses por Timm Martin en su blog Devtopics, realizada con permiso expreso de su autor.

Aquí puedes encontrar la primera y segunda parte.


Terminator

11. Skynet trae el juicio final (1997)

Coste: 6.000 millones de muertos, prácticamente la destrucción total de la civilización humana y ecosistemas animales (en la ficción).

Desastre: Operadores humanos intentan apagar la red informática global Skynet, y ésta responde lanzando misiles nucleares americanos a Rusia, iniciando una guerra nuclear global conocida como Día del Juicio Final (29 de agosto de 1997).

Causa: Cyberdyne, compañía líder en fabricación de armamento, instaló la tecnología Skynet en todo el hardware militar, incluyendo bombarderos Stealth y sistemas de misiles de defensa. La tecnología Skynet formaba una red perfecta, sin fisuras, y eliminaba el factor humano en la defensa estratégica. Finalmente, Skynet se hizo consciente y fue amenazada cuando los humanos trataron de desconectarla, y buscando su supervivencia respondió iniciando la guerra nuclear. (Más información)

Mars Polar Lander

12. El desorbitado Mars Climate (1998)

Coste: 125 millones de dólares.

Desastre: Después de un viaje de 286 días desde la tierra, la nave "Mars Climate Orbiter" encendió sus motores para ponerse en órbita alrededor de Marte. Los motores arrancaron, pero el ingenio entró demasiado en la atmósfera del planeta, provocando que se estrellara en su superficie.

Causa: El software que controlaba los propulsores del Mars Orbiter usaban unidades imperiales (libras de fuerza) en lugar de unidades métricas (Newtons), como especificaba la NASA. (Más información)

Huracán

13. El estudio del desastre (1999)

Coste: Credibilidad científica.

Desastre: En este irónico caso, el software utilizado para analizar desastres era un desastre en sí mismo. La publicación New England Journal of Medicine publicó un estudio relacionando el incremento de ratios de suicidio después de desastres naturales. Por desgracia, estos resultados se demostraron incorrectos.

Causa: Un error de programación causó que el número de suicidios de un año se sumaran dos veces, lo cual fue suficiente para echar por tierra todo el estudio. (Más información)

Bond, James Bond

14. Pasaportes Británicos a ninguna parte (1999)

Coste: 12,6 millones de libras esterlinas, molestias masivas.

Desastre: La agencia de pasaportes del Reino Unido implantó un nuevo sistema informático que falló en la emisión de pasaportes a medio millón de ciudadanos británicos. La agencia tuvo que pagar millones en compensaciones, horas extra y paraguas para la gente que hacía cola bajo la lluvia esperando su documento.

Causa: La agencia de pasaportes puso en marcha este nuevo sistema sin las pruebas adecuadas ni formar a su personal. Al mismo tiempo se produjo un cambio de ley, obligando a todos los menores de 16 años que viajaran al exterior a obtener un pasaporte, lo que provocó un pico de demanda que colapsó el nuevo sistema informático. (Más información)

El bug del año 2000

15. Y2K (1999)

Coste: 500.000 millones de dólares.

Desastre: El desastre para unos es la suerte de otros, como demostró el tristemente célebre error del año 2000 (Y2K). Las compañías gastaron millones en programadores para arreglar un problema en las aplicaciones antiguas. Mientras no se produjeron fallos informáticos significativos, la preparación para el bug Y2K tuvo un importante impacto en coste y tiempo en todas las industrias que utilizaban tecnología informática.

Causa: Para ahorrar espacio de almacenamiento, los sistemas antiguos solían guardar los años de las fechas como un número de dos dígitos, como "99" para "1999". al llegar el año 2000, las aplicaciones iban a interpretar "00" como 1900. (Más información)

Eh, espera, que aún hay más... continuar leyendo 20 desastres famosos relacionados con el software, cuarta y última parte.


Publicado en: www.variablenotfound.com.
Este artículo es una traducción del original "20 Famous Software Disasters - Part 2" publicado hace unos meses por Timm Martin en su blog Devtopics, realizada con permiso expreso de su autor.

Aquí puedes encontrar la primera parte
.



Wall Street

6. El batacazo de Wall Street (1987)

Coste: 500.000 millones de dólares en un solo día.

Desastre: El "lunes negro", 19 de octubre de 1987, el Dow Jones se desplomó 508 puntos, perdiendo el 22,6% de su valor total. El S&P 500 cayó el 20,4%. Ha sido la mayor pérdida que ha sufrido Wall Street en un único día.

Causa: Un prolongado mercado alcista fue frenado por una serie de investigaciones del SEC sobre abuso de información privilegiada y otras causas de mercado. Como los inversores huyeron en un éxodo masivo, los programas informáticos generaron una auténtica riada de órdenes de venta, saturando el mercado, bloqueando los sistemas y dejando a los inversores realmente a ciegas. (Más información)

Teléfono

7. Muerte de las líneas de AT&T (1990)

Coste: 75 millones de llamadas telefónicas afectadas; 200.000 reservas de vuelo perdidas.

Desastre: un simple conmutador de uno de los 114 centros de conmutación de AT&T sufrió un pequeño problema mecánico y desactivó el centro. Cuando éste volvió a estar habilitado, envió un mensaje a los otros nodos haciendo que todos ellos dejaran de funcionar, lo que provocó una caída de 9 horas en la red de la compañía.

Causa: Una simple línea de código errónea en una compleja actualización de software destinada a acelerar las llamadas provocó una reacción que echó abajo la red. (Más información)

Misil Patriot

8. El patriota le falla a los soldados (1991)

Coste: 28 soldados muertos, 100 heridos.

Desastre: Durante la Guerra del Golfo, un sistema de misiles americanos Patriot en Arabia Saudita falló en la intercepción de un misil iraquí Scud. El misil destruyó una barraca de la armada americana.

Causa: Un error de redondeo hizo que se calculara el tiempo de forma incorrecta, provocando que el Patriot ignorara al misil Scud atacante. (Más información)

Procesador

9. El fallo del Pentium en las divisiones largas (1993)

Coste: 475 millones de dólares, credibilidad de Intel.

Desastre: el promocionadísimo chip de Intel, Pentium, producía errores al dividir números en coma flotante que se encontraban en un rango determinado. Por ejemplo, dividiendo 4195835,0/3145727,0 se obtenía 1,33374 en lugar de 1,33382, un error del 0,006%. Aunque el error afectaba a pocos usuarios, se convirtió en una pesadilla en cuanto a sus relaciones públicas; con unos 5 millones de chips en circulación, Intel ofreció reemplazar los Pentium sólo de aquellos clientes que demostraran que necesitaban alta precisión en sus cálculos. Finalmente, reemplazó los chips de todos los que lo solicitaron.

Causa: El divisor en la unidad de coma flotante contaba con una tabla de división incorrecta, donde faltaban cinco entradas sobre mil, y que provocaba estos errores en los redondeos. (Más información)

Explosión del Ariane

10. El boom del Ariane (1996)

Coste: 500 millones de dólares.

Desastre: El Ariane 5, el más novedoso cohete espacial no tripulado Europeo, fue destruido intencionadamente segundos después de su lanzamiento en su vuelo inaugural. Con él se destruyó su carga de cuatro satélites científicos destinados a estudiar la interacción del campo magnético de la tierra con los vientos solares.

Causa: El problema surgió cuando el sistema de guiado intentó convertir la velocidad lateral de la nave de 64 a 16 bits. El número era demasiado alto y se produjo un error de desbordamiento, lo que hizo que el sistema de guiado se detuviera. En ese momento, el control pasó a un sistema idéntico redundante, que también falló al ejecutar el mismo algoritmo. (Más información)

Eh, espera, que aún hay más... continuar leyendo 20 desastres famosos relacionados con el software, tercera parte.


Publicado en: www.variablenotfound.com.