Как взорвать ракету одной переменной
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)))

Обложка:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Маша Климентьева

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

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

hard
Как сделать свой сайт за 10 минут без программирования

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

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

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

easy
Сложная задача про длину кабеля

Потребуется логика и воображение

easy
Кто прав?
Откуда взялась тысяча?

Классическая задача на абстрактное мышление и логику.

easy
Задача про часы, программиста и бабушку

Несложная задача для решения в уме

easy
Нереальная задача про программистов и их логическое мышление

Логика — сила!

easy
Макроэкономическая задача про кино

Философия и математика на страже упущенных возможностей

easy
easy
[anycomment]
Exit mobile version