Как взорвать ракету одной переменной
easy

Как взорвать ракету одной переменной

Краткий мастер-класс по правильному объявлению типов данных.

Что произошло

Ошибки в коде бывают у всех, но их последствия всегда разные. Одно дело — ошибиться в программе для шагомера и потерять 500 шагов, и другое — лишиться полумиллиарда долларов.

Эта история произошла в 1996 году, когда Европейское космическое агентство потеряло космическую ракету-носитель Ariane-5 из-за неправильно объявленной переменной. Через 40 секунд после старта ракета взорвалась в воздухе, полностью уничтожив четыре спутника, которые нужно было вывести на орбиту.

Когда комиссия начала расследование, она выяснила, что во всём виновата одна переменная, которая не могла принимать значение больше, чем 32 767. Этого оказалось достаточно, чтобы всё вышло из-под контроля.

Ракета-носитель Ariane-5, фото из Википедии

В чём причина

В летательном аппарате был модуль, который отвечал за ориентировку в пространстве, — инерционная система ориентировки, ИСО. Европейцы ставили этот элемент на все ракеты, допиливая его под разные задачи. Ariane-5 достался модуль от Ariane-4. Думали, что раз он прекрасно показал себя на предыдущем аппарате, то и на новом тоже всё заработает.

Ракета Ariane-4 летала не так быстро, как Ariane-5, и модуль мог спокойно посчитать всё, что ему было нужно, используя переменные в диапазоне от −32 768 до 32 767. Причём этот промежуток был с запасом: в реальности такие числа на Ariane-4 не использовались.

Но Ariane-5 летала намного быстрее. Переменные очень скоро достигли своего максимального значения и вызвали сбой. Включился резервный модуль, но в нём стоял точно такой же софт от старой ракеты, который сделал всё то же самое: быстро достиг потолка в переменной и тоже вызвал сбой. Ariane-5 продолжала ускоряться.

Через 40 секунд после старта ракета набрала такую высокую скорость, что аэродинамическая нагрузка стала критической: обшивка начала разрушаться, стартовые двигатели отделились, и аппарат взорвался.

Память у компьютеров не резиновая. Когда мы пишем программу и нужно в ней что-то запомнить, мы говорим компьютеру: «Выдели нам память для такой-то информации».

Есть языки программирования, где место для данных выделяется автоматически. Например, в JavaScript просто говоришь: «Вот новая переменная, положи в неё вот это», — и система сама определит, сколько на эту информацию нужно памяти. Есть языки, где необходимо чётко сказать, какого типа переменную следует создать. Например, в языке C:

int speed;
speed = 99;

Int означает integer, то есть целое число. На целое число выделяется сколько-то памяти, в зависимости от языка. Чтобы не погружаться в битность и сложности двоичного счисления, представьте такую ситуацию.

Вы делаете инвентаризацию товаров на складе. По каждой позиции вы заполняете форму, в которой есть поле «Порядковый номер». В этой графе три пустых клетки, которые вы можете заполнить цифрами от 0 до 9. Если начинать с товара 001, то максимальное количество позиций, которое вы можете посчитать с помощью этих трёх клеток, — 999.

[0] [0] [1]

[0] [0] [2]

[0] [0] [3]

...

[9] [9] [9]

Если у вас на складе лежит более 999 товаров, вам потребуется какая-то другая форма, в которой будет уже не три, а четыре клетки. Или можно объявить программный сбой и уйти на обед.

Вот это и произошло с ракетой:

  1. Ракете дали, грубо говоря, 16 клеток, чтобы записать какой-то параметр скорости.
  2. Максимальное число, которое можно было записать на компьютере, используя 16 компьютерных клеток, — 65 535.
  3. Если нам нужны числа с плюсами и минусами, то мы получаем диапазон значений от −32 768 до +32 767.
  4. Всё, что выходит за рамки этого промежутка, компьютер уже не может записать — так же, как мы не можем внести в три клетки число более 999.
  5. Программе нужно было записать число больше, чем 32 767. А клеток не хватает!
  6. Дальше вы знаете.

Вот так одна строка кода может пустить на ветер кучу денег и стать одной из самых дорогих ошибок в истории программирования. А вот та самая строка:

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

Любите данные? Посмотрите вот это
Возможно, у вас получится построить карьеру в мире дата-сайенса. Это новое направление, в котором очень нужны люди. Изучите эту сферу и начните карьеру в ИТ: старт — бесплатно, а после обучения — помощь с трудоустройством.
Начать бесплатно
Любите данные? Посмотрите вот это Любите данные? Посмотрите вот это Любите данные? Посмотрите вот это Любите данные? Посмотрите вот это
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Как сделать свой сайт за 10 минут без программирования

Для некоторых это становится источником постоянного дохода, если подойти к процессу с умом.

easy
Как разделить неделимое наследство

Старая, но интересная задача про то, как выполнить невыполнимое условие.

hard
Захватят ли нанороботы мир?
Захватят ли нанороботы мир?

Моделируем ход техногенной катастрофы с помощью простого уравнения.

easy
10 отличных задач на логику
10 отличных задач на логику

От простых до школьных

hard
Задача с подвохом
Сложная задача про бабушку и домашние помидоры
medium
Логическая задача
Задача имени Якубовича: три шкатулки с деньгами

Интуиция обманет вас в этой задаче. Попробуйте лучше теорию вероятностей, это легко.

hard
Быстрая задача про время
Быстрая задача про время

Если сможете решить в уме — наше почтение

easy
Нестандартная задача про наши счастливые годы: 2020-й и 2021-й
Нестандартная задача про наши счастливые годы: 2020-й и 2021-й

С виду она очень простая, но это не так

medium
Задача про ниндзя и разведчика
Задача про ниндзя и разведчика

Победитель может быть только один.

medium
easy