Ошибка с плавающей запятой, которая нанесла ущерб на полмиллиарда
Если вы когда-либо немного занимались программированием, вы должны знать термин: плавающая точка. Одной из наиболее игнорируемых и потенциально опасных ошибок, с которыми можно столкнуться, является ошибка с плавающей запятой.
Могу поспорить, что программист должен был видеть ошибку с плавающей запятой хотя бы раз в жизни. Но какой ущерб может нанести ошибка с плавающей запятой? Спросите об этом Европейское космическое агентство, которое потеряло более десяти лет усилий и 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)));
Дальнейшее чтение:
Эти ссылки могут пригодиться, если вы хотите прочитать об этом дорогостоящем случае ошибки с плавающей запятой: