Поиск по сайту:

Ошибка с плавающей запятой, которая нанесла ущерб на полмиллиарда


Если вы когда-либо немного занимались программированием, вы должны знать термин: плавающая точка. Одной из наиболее игнорируемых и потенциально опасных ошибок, с которыми можно столкнуться, является ошибка с плавающей запятой.

Могу поспорить, что программист должен был видеть ошибку с плавающей запятой хотя бы раз в жизни. Но какой ущерб может нанести ошибка с плавающей запятой? Спросите об этом Европейское космическое агентство, которое потеряло более десяти лет усилий и 500 миллионов долларов из-за ошибки с плавающей запятой.

История Арианы 5:

4 июня 1996 года первый полет ракеты-носителя «Ариан-5» завершился неудачей. Всего примерно через 40 секунд после начала полета, на высоте около 3700 м, пусковая установка отклонилась от траектории полета, распалась и взорвалась.

Отказ Ariane 501 был вызван полной потерей информации о наведении и ориентации через 37 секунд после начала последовательности зажигания основного двигателя (30 секунд после взлета). Эта потеря информации произошла из-за ошибок в спецификации и проектировании программного обеспечения инерциальной системы отсчета.

Внутреннее программное исключение SRI* возникло во время преобразования данных из 64-битного числа с плавающей запятой в 16-битное целое число со знаком. Преобразованное число с плавающей запятой имело значение, превышающее то, которое могло быть представлено 16-битным целым числом со знаком.

Итак, что именно произошло?

64-битное число с плавающей запятой, относящееся к горизонтальной скорости ракеты относительно платформы, было преобразовано в 16-битное целое число со знаком. Число было больше 32 767, самого большого целого числа, которое можно сохранить в 16-битном целом со знаком, поэтому преобразование не удалось.

Программное обеспечение в конечном итоге запустило диагностику системы, которая сбросила отладочные данные в область памяти, используемую программами, управляющими двигателями ракеты. В то же время управление было переключено на резервный компьютер, который, к сожалению, имел те же данные.

Это было ошибочно истолковано как необходимость решительных корректирующих действий, и двигатели ракеты развернулись до предела своих опор. Произошла катастрофа.

Кодирование было выполнено на Ada. Последняя строка – вот что стало причиной трагедии:

L_M_BV_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BV) * G_M_INFO_DERIVE(T_ALG.E_BV));

if L_M_BV_32 > 32767 then
    P_M_DERIVE(T_ALG.E_BV) := 16#7FFF#;
elsif L_M_BV_32 < -32768 then
    P_M_DERIVE(T_ALG.E_BV) := 16#8000#;
else
    P_M_DERIVE(T_ALG.E_BV) := UC_16S_EN_16NS(TDB.T_ENTIER_16S(L_M_BV_32));
end if;

P_M_DERIVE(T_ALG.E_BH) := 
  UC_16S_EN_16NS (TDB.T_ENTIER_16S ((1.0/C_M_LSB_BH) * G_M_INFO_DERIVE(T_ALG.E_BH)));

Дальнейшее чтение:

Эти ссылки могут пригодиться, если вы хотите прочитать об этом дорогостоящем случае ошибки с плавающей запятой:

Статьи по данной тематике: