HTML Diff
1 added 1 removed
Original 2026-01-01
Modified 2026-02-21
1 <p><a>#статьи</a></p>
1 <p><a>#статьи</a></p>
2 <ul><li>5 апр 2023</li>
2 <ul><li>5 апр 2023</li>
3 <li>0</li>
3 <li>0</li>
4 </ul><h2>Числа с плавающей точкой: что это такое и как они работают</h2>
4 </ul><h2>Числа с плавающей точкой: что это такое и как они работают</h2>
5 <p>Рассказываем, как дробные числа хранятся в памяти компьютера - всё сложно и волшебно, но оправданно.</p>
5 <p>Рассказываем, как дробные числа хранятся в памяти компьютера - всё сложно и волшебно, но оправданно.</p>
6 <p>Иллюстрация: Катя Павловская для Skillbox Media</p>
6 <p>Иллюстрация: Катя Павловская для Skillbox Media</p>
7 <p>Любитель научной фантастики и технологического прогресса. Хорошо сочетает в себе заумного технаря и утончённого гуманитария. Пишет про IT и радуется этому.</p>
7 <p>Любитель научной фантастики и технологического прогресса. Хорошо сочетает в себе заумного технаря и утончённого гуманитария. Пишет про IT и радуется этому.</p>
8 <p>Компьютеры придумали, чтобы производить вычисления более точно и быстро. Но парадокс в том, что на самом деле их вычисления почти всегда неточны. Например, мы не можем представить число Пи или корень из двух в памяти компьютера - потому что имеем дело с бесконечной дробью (хотя и с "короткими" числами всё не так просто из-за двоичной системы счисления, в которой числа представлены в памяти компьютера, к этому мы тоже вернёмся).</p>
8 <p>Компьютеры придумали, чтобы производить вычисления более точно и быстро. Но парадокс в том, что на самом деле их вычисления почти всегда неточны. Например, мы не можем представить число Пи или корень из двух в памяти компьютера - потому что имеем дело с бесконечной дробью (хотя и с "короткими" числами всё не так просто из-за двоичной системы счисления, в которой числа представлены в памяти компьютера, к этому мы тоже вернёмся).</p>
9 <p>Так что компьютер в какой-то момент идёт на уступки и ограничивается вычислениями с той точностью, которая необходима для решения стоящей за ними практической задачи.</p>
9 <p>Так что компьютер в какой-то момент идёт на уступки и ограничивается вычислениями с той точностью, которая необходима для решения стоящей за ними практической задачи.</p>
10 <p>Чтобы эффективно проводить вычисления, учёные придумали числа с плавающей точкой - они стали отличным инструментом для представления вещественных чисел (это, по сути, все числа числового ряда, даже те, у которых дробная часть бесконечна).</p>
10 <p>Чтобы эффективно проводить вычисления, учёные придумали числа с плавающей точкой - они стали отличным инструментом для представления вещественных чисел (это, по сути, все числа числового ряда, даже те, у которых дробная часть бесконечна).</p>
11 <p>Под числа с плавающей точкой даже создан единый стандарт IEEE 754 - чтобы все компьютеры, языки программирования, программы и операционные системы работали с ними одинаково и результат получался предсказуемым. В этой статье мы расскажем, что это за стандарт и как он работает.</p>
11 <p>Под числа с плавающей точкой даже создан единый стандарт IEEE 754 - чтобы все компьютеры, языки программирования, программы и операционные системы работали с ними одинаково и результат получался предсказуемым. В этой статье мы расскажем, что это за стандарт и как он работает.</p>
12 <p>1970-е годы, начало компьютерной революции. Учёные-программисты разрабатывают новые компьютеры и алгоритмы для вычислений, а также стараются всеми силами доказать, что их изобретения должны изменить мир.</p>
12 <p>1970-е годы, начало компьютерной революции. Учёные-программисты разрабатывают новые компьютеры и алгоритмы для вычислений, а также стараются всеми силами доказать, что их изобретения должны изменить мир.</p>
13 <p>Тогда все компьютеры работали по-разному: у них были собственные операционные системы, принципы организации памяти и способы представления данных. И это создавало проблему: нельзя было перенести программу с одного компьютера на другой, для этого каждый раз приходилось переписывать её под новую систему и "железо".</p>
13 <p>Тогда все компьютеры работали по-разному: у них были собственные операционные системы, принципы организации памяти и способы представления данных. И это создавало проблему: нельзя было перенести программу с одного компьютера на другой, для этого каждый раз приходилось переписывать её под новую систему и "железо".</p>
14 - <p>И если переделать пару функций было не так сложно, то подстраиваться под разные системы представления чисел было действительно мукой. Из-за этого иногда нужно было полностью менять поведение программы, что могло повлиять на её работоспособность и надёжность. В общем - проблема с представлениями чисел был поистине болезненной.</p>
14 + <p>И если переделать пару функций было не так сложно, то подстраиваться под разные системы представления чисел было действительно мукой. Из-за этого иногда нужно было полностью менять поведение программы, что могло повлиять на её работоспособность и надёжность. В общем - проблема с представлениями чисел была поистине болезненной.</p>
15 Такие компьютеры были в продаже в 1980-х годах<em>Фото:<a>Wikimedia Commons</a></em><p>Компания Intel решила помочь программистам со всего мира и создать единый стандарт представления вещественных чисел. Для этого была создана проектная группа из лучших инженеров. Но на пятки Intel наступали и другие компании - например, у той же DEC появилась похожая идея.</p>
15 Такие компьютеры были в продаже в 1980-х годах<em>Фото:<a>Wikimedia Commons</a></em><p>Компания Intel решила помочь программистам со всего мира и создать единый стандарт представления вещественных чисел. Для этого была создана проектная группа из лучших инженеров. Но на пятки Intel наступали и другие компании - например, у той же DEC появилась похожая идея.</p>
16 <p>Началась настоящая гонка за лучшее решение: каждая компания фанатела исключительно от своей разработки и надеялась, что именно её примут как промышленный стандарт. А IT-гиганты IBM и Cray наблюдали за всем происходящим со стороны и ждали, пока появится победитель, - чтобы тут же реализовать его стандарт в своих компьютерах.</p>
16 <p>Началась настоящая гонка за лучшее решение: каждая компания фанатела исключительно от своей разработки и надеялась, что именно её примут как промышленный стандарт. А IT-гиганты IBM и Cray наблюдали за всем происходящим со стороны и ждали, пока появится победитель, - чтобы тут же реализовать его стандарт в своих компьютерах.</p>
17 <p>Сегодня из всех стандартов, возникших в то время, в живых остались только два: спецификация<a>VAX</a>от DEC и <a>K-C-S</a>от Intel. У каждой из них были как свои преимущества, так и недостатки.</p>
17 <p>Сегодня из всех стандартов, возникших в то время, в живых остались только два: спецификация<a>VAX</a>от DEC и <a>K-C-S</a>от Intel. У каждой из них были как свои преимущества, так и недостатки.</p>
18 <p>Преимущества K-C-S:</p>
18 <p>Преимущества K-C-S:</p>
19 <ul><li><strong>Десятичный формат.</strong>Он позволял представлять вещественные числа в десятичной записи, что очень удобно для человека, но так себе для компьютера.</li>
19 <ul><li><strong>Десятичный формат.</strong>Он позволял представлять вещественные числа в десятичной записи, что очень удобно для человека, но так себе для компьютера.</li>
20 <li><strong>Высокая точность.</strong>Десятичное представление повышало точность вычислений и снижало возникновение ошибок при округлении - особенно для операций с большими числами.</li>
20 <li><strong>Высокая точность.</strong>Десятичное представление повышало точность вычислений и снижало возникновение ошибок при округлении - особенно для операций с большими числами.</li>
21 <li><strong>Меньше ошибок.</strong>Стандарт включал специальные значения, которые помогали легко избегать переполнения чисел и проще справляться с ошибками при вычислениях.</li>
21 <li><strong>Меньше ошибок.</strong>Стандарт включал специальные значения, которые помогали легко избегать переполнения чисел и проще справляться с ошибками при вычислениях.</li>
22 </ul><p>Преимущества VAX:</p>
22 </ul><p>Преимущества VAX:</p>
23 <ul><li><strong>Двоичный формат.</strong>Все числа записывались только в двоичном представлении, что повышало эффективность вычислений, особенно на компьютерах с VAX-архитектурой.</li>
23 <ul><li><strong>Двоичный формат.</strong>Все числа записывались только в двоичном представлении, что повышало эффективность вычислений, особенно на компьютерах с VAX-архитектурой.</li>
24 <li><strong>Широкое распространение.</strong>Спецификацию VAX уже использовали на разных компьютерах того времени, что позволяло быстро адаптировать её под новые устройства.</li>
24 <li><strong>Широкое распространение.</strong>Спецификацию VAX уже использовали на разных компьютерах того времени, что позволяло быстро адаптировать её под новые устройства.</li>
25 <li><strong>Высокая производительность.</strong>Спецификация VAX была оптимизирована под высокую скорость работы и требовала меньших вычислительных мощностей.</li>
25 <li><strong>Высокая производительность.</strong>Спецификация VAX была оптимизирована под высокую скорость работы и требовала меньших вычислительных мощностей.</li>
26 </ul><strong>K-C-S</strong><strong>VAX</strong>Десятичный форматДвоичный форматВысокая точностьВысокая производительностьМеньше ошибокШирокая распространённость<p>Компания DEC пыталась сделать всё, чтобы VAX признали единым стандартом. Она даже пыталась убедить авторитетных учёных в том, что конкурирующий K-C-S никогда не станет таким же производительным и успешным. Однако у разработчиков из Intel были свои секретики: например, они знали, как ускорить свою спецификацию и обогнать DEC.</p>
26 </ul><strong>K-C-S</strong><strong>VAX</strong>Десятичный форматДвоичный форматВысокая точностьВысокая производительностьМеньше ошибокШирокая распространённость<p>Компания DEC пыталась сделать всё, чтобы VAX признали единым стандартом. Она даже пыталась убедить авторитетных учёных в том, что конкурирующий K-C-S никогда не станет таким же производительным и успешным. Однако у разработчиков из Intel были свои секретики: например, они знали, как ускорить свою спецификацию и обогнать DEC.</p>
27 <p>В итоге победила Intel, а её спецификация легла в основу стандарта IEEE 754, который утвердил Институт инженеров электротехники и электроники (IEEE) в 1985 году.</p>
27 <p>В итоге победила Intel, а её спецификация легла в основу стандарта IEEE 754, который утвердил Институт инженеров электротехники и электроники (IEEE) в 1985 году.</p>
28 <p>Чтобы понять стандарт IEEE 754, нам нужно сперва разобраться, как числа представляют в двоичной системе. Всего существует два представления десятичных чисел в компьютере: с плавающей точкой и фиксированной. Первые основаны на вторых, поэтому есть смысл начать с них.</p>
28 <p>Чтобы понять стандарт IEEE 754, нам нужно сперва разобраться, как числа представляют в двоичной системе. Всего существует два представления десятичных чисел в компьютере: с плавающей точкой и фиксированной. Первые основаны на вторых, поэтому есть смысл начать с них.</p>
29 <p>И да, дальше мы будем употреблять слово "точка", однако в других статьях и литературе можно встретить термин "запятая". Они означают одно и то же, но в англоговорящих странах чаще используют второй, а в русскоговорящих - первый.</p>
29 <p>И да, дальше мы будем употреблять слово "точка", однако в других статьях и литературе можно встретить термин "запятая". Они означают одно и то же, но в англоговорящих странах чаще используют второй, а в русскоговорящих - первый.</p>
30 <p>Числа с фиксированной точкой - это<a>двоичные числа</a>, у которых ограничен размер их целой и дробной части. Например, если число состоит из 16 битов, то мы можем выделить для целой части первые 10 битов и оставшиеся шесть - для дробной части.</p>
30 <p>Числа с фиксированной точкой - это<a>двоичные числа</a>, у которых ограничен размер их целой и дробной части. Например, если число состоит из 16 битов, то мы можем выделить для целой части первые 10 битов и оставшиеся шесть - для дробной части.</p>
31 <p>Разделение между целой и дробной частью как раз и обозначают точкой. Когда компьютер получает число, он сразу понимает, что в нём 2 байта, или 16 битов, из которых 10 - это целая часть, а шесть - дробная. Получится так:</p>
31 <p>Разделение между целой и дробной частью как раз и обозначают точкой. Когда компьютер получает число, он сразу понимает, что в нём 2 байта, или 16 битов, из которых 10 - это целая часть, а шесть - дробная. Получится так:</p>
32 <em>Изображение: Skillbox Media</em><p>На картинке - двоичное представление десятичного числа 689.6875 в виде двоичного числа с фиксированной точкой. Вот ещё один пример с числом поменьше:</p>
32 <em>Изображение: Skillbox Media</em><p>На картинке - двоичное представление десятичного числа 689.6875 в виде двоичного числа с фиксированной точкой. Вот ещё один пример с числом поменьше:</p>
33 <em>Изображение: Skillbox Media</em><p>Здесь закодировано число 13.0. Видим, что в дробной части одни нули и, соответственно, дробная часть десятичного числа - нулевая.</p>
33 <em>Изображение: Skillbox Media</em><p>Здесь закодировано число 13.0. Видим, что в дробной части одни нули и, соответственно, дробная часть десятичного числа - нулевая.</p>
34 <p>Давайте подробнее разберём, почему всё получилось именно так. Сначала посмотрим на целую часть - это обычное представление десятичного числа в двоичной записи. Каждый разряд числа относится к степени двойки. Число из примера выше можно разложить так:</p>
34 <p>Давайте подробнее разберём, почему всё получилось именно так. Сначала посмотрим на целую часть - это обычное представление десятичного числа в двоичной записи. Каждый разряд числа относится к степени двойки. Число из примера выше можно разложить так:</p>
35 <em>Изображение: Skillbox Media</em><p>Чтобы перевести двоичную запись в десятичную, нужно сложить все степени двойки, у которых в разряде стоит единица. Получим:</p>
35 <em>Изображение: Skillbox Media</em><p>Чтобы перевести двоичную запись в десятичную, нужно сложить все степени двойки, у которых в разряде стоит единица. Получим:</p>
36 <em>Изображение: Skillbox Media</em><p>Теперь рассмотрим дробную часть. Принцип перевода дробной части двоичного числа в десятичную систему такой же. Единственное отличие в том, что там степени двойки - отрицательные. Рассмотрим число из примера выше:</p>
36 <em>Изображение: Skillbox Media</em><p>Теперь рассмотрим дробную часть. Принцип перевода дробной части двоичного числа в десятичную систему такой же. Единственное отличие в том, что там степени двойки - отрицательные. Рассмотрим число из примера выше:</p>
37 <em>Изображение: Skillbox Media</em><p>Степень двойки начинается с -1 и с каждым разрядом уменьшается на единицу: -2, -3 и так далее, а чтобы перевести её из отрицательной в положительную, нужно просто перевернуть дробь. И теперь мы также складываем все степени двойки, у которых в соответствующем разряде стоит единица:</p>
37 <em>Изображение: Skillbox Media</em><p>Степень двойки начинается с -1 и с каждым разрядом уменьшается на единицу: -2, -3 и так далее, а чтобы перевести её из отрицательной в положительную, нужно просто перевернуть дробь. И теперь мы также складываем все степени двойки, у которых в соответствующем разряде стоит единица:</p>
38 <em>Изображение: Skillbox Media</em><p>Теперь нам осталось сложить целую часть с дробной:</p>
38 <em>Изображение: Skillbox Media</em><p>Теперь нам осталось сложить целую часть с дробной:</p>
39 <em>Изображение: Skillbox Media</em><p>Преимущества чисел с фиксированной точкой в том, что они всегда представляются в виде конечного числа. Это значит, что если мы захотим представить число Пи, то оно будет ограничено на определённом знаке, а остальные мы просто отбросим. Например, так:</p>
39 <em>Изображение: Skillbox Media</em><p>Преимущества чисел с фиксированной точкой в том, что они всегда представляются в виде конечного числа. Это значит, что если мы захотим представить число Пи, то оно будет ограничено на определённом знаке, а остальные мы просто отбросим. Например, так:</p>
40 <em>Изображение: Skillbox Media</em><p>Это число - приближённое представление числа Пи, и оно не является его точным значением.</p>
40 <em>Изображение: Skillbox Media</em><p>Это число - приближённое представление числа Пи, и оно не является его точным значением.</p>
41 <p>Недостатки у чисел с фиксированной точкой, конечно же, тоже есть. Например, если мы возьмём 16-битные числа, у которых первые 10 битов относятся к целой части и остальные шесть - к дробной, то в нашем распоряжении окажется такой диапазон значений:</p>
41 <p>Недостатки у чисел с фиксированной точкой, конечно же, тоже есть. Например, если мы возьмём 16-битные числа, у которых первые 10 битов относятся к целой части и остальные шесть - к дробной, то в нашем распоряжении окажется такой диапазон значений:</p>
42 <em>Изображение: Skillbox Media</em><p>И тут мы переходим к главному недостатку чисел с фиксированной точкой. Давайте возьмём самое большое число, которое можно записать таким образом, и вычислим число перед ним, то есть такое число:</p>
42 <em>Изображение: Skillbox Media</em><p>И тут мы переходим к главному недостатку чисел с фиксированной точкой. Давайте возьмём самое большое число, которое можно записать таким образом, и вычислим число перед ним, то есть такое число:</p>
43 <em>Изображение: Skillbox Media</em><p>Видим интересное: когда мы убрали одну единицу в конце двоичного числа, то получили разницу между двумя числами не 0.000001, как в десятичных числах, а 0.015625. Это число представляет собой как бы минимальный шаг в числах с фиксированной точкой, или максимально возможную точность.</p>
43 <em>Изображение: Skillbox Media</em><p>Видим интересное: когда мы убрали одну единицу в конце двоичного числа, то получили разницу между двумя числами не 0.000001, как в десятичных числах, а 0.015625. Это число представляет собой как бы минимальный шаг в числах с фиксированной точкой, или максимально возможную точность.</p>
44 <p>Если мы возьмём следующее число, то разница останется такой же:</p>
44 <p>Если мы возьмём следующее число, то разница останется такой же:</p>
45 <em>Изображение: Skillbox Media</em><p>Эта точность, во-первых, позволяет превращать десятичные числа в двоичные, а во-вторых, уменьшает нагрузку на компьютер, ведь компьютер всегда знает, что первые 10 битов - это целая часть, а оставшиеся шесть - дробная.</p>
45 <em>Изображение: Skillbox Media</em><p>Эта точность, во-первых, позволяет превращать десятичные числа в двоичные, а во-вторых, уменьшает нагрузку на компьютер, ведь компьютер всегда знает, что первые 10 битов - это целая часть, а оставшиеся шесть - дробная.</p>
46 <p>С фиксированной точкой разобрались, теперь перейдём к плавающей, а затем узнаем уже о формате IEEE 754.</p>
46 <p>С фиксированной точкой разобрались, теперь перейдём к плавающей, а затем узнаем уже о формате IEEE 754.</p>
47 <p>Если говорить техническим языком, то число с плавающей точкой (или число с плавающей запятой) - это численное представление вещественного числа в программировании. Иначе говоря, оно является его приближённым значением.</p>
47 <p>Если говорить техническим языком, то число с плавающей точкой (или число с плавающей запятой) - это численное представление вещественного числа в программировании. Иначе говоря, оно является его приближённым значением.</p>
48 <p>Двоичное представление чисел с плавающей точкой содержит три части: знаковый бит, экспоненту и мантиссу.</p>
48 <p>Двоичное представление чисел с плавающей точкой содержит три части: знаковый бит, экспоненту и мантиссу.</p>
49 <ul><li><strong>Знаковый бит</strong>указывает, положительное число или отрицательное.</li>
49 <ul><li><strong>Знаковый бит</strong>указывает, положительное число или отрицательное.</li>
50 <li><strong>Экспонента</strong>показывает, на какое число нужно умножать мантиссу.</li>
50 <li><strong>Экспонента</strong>показывает, на какое число нужно умножать мантиссу.</li>
51 <li><strong>Мантисса</strong> - это фиксированное количество битов, которое выражает точность числа.</li>
51 <li><strong>Мантисса</strong> - это фиксированное количество битов, которое выражает точность числа.</li>
52 </ul><p>Эти определения слегка сложноваты, поэтому давайте сначала разберёмся с основами.</p>
52 </ul><p>Эти определения слегка сложноваты, поэтому давайте сначала разберёмся с основами.</p>
53 <p>В научной нотации числа удобнее представлять как что-то небольшое, умноженное на 10 в какой-то степени. Например, число 123.456 удобнее представить в виде 1.23456 × 102 Это удобнее, потому что для умножения двух чисел в таком виде не приходится тратить много сил. Звучит неочевидно, но давайте посмотрим на практике - умножим число 0.0006 на 0.0002:</p>
53 <p>В научной нотации числа удобнее представлять как что-то небольшое, умноженное на 10 в какой-то степени. Например, число 123.456 удобнее представить в виде 1.23456 × 102 Это удобнее, потому что для умножения двух чисел в таком виде не приходится тратить много сил. Звучит неочевидно, но давайте посмотрим на практике - умножим число 0.0006 на 0.0002:</p>
54 <em>Изображение: Skillbox Media</em><p>Как мы видим, в научной нотации нужно было просто сложить степени и произвести несложное умножение. А в обычном виде нам нужно было умножить два числа и ещё не запутаться, сколько нулей слева нужно дописывать. Одним словом - научная нотация проще.</p>
54 <em>Изображение: Skillbox Media</em><p>Как мы видим, в научной нотации нужно было просто сложить степени и произвести несложное умножение. А в обычном виде нам нужно было умножить два числа и ещё не запутаться, сколько нулей слева нужно дописывать. Одним словом - научная нотация проще.</p>
55 <p>В этой нотации число состоит тоже из трёх компонентов: экспоненты, коэффициента, мантиссы и знака числа.</p>
55 <p>В этой нотации число состоит тоже из трёх компонентов: экспоненты, коэффициента, мантиссы и знака числа.</p>
56 <ul><li><strong>Знак числа</strong>указывает, какое это число: положительное или отрицательное. Он нужен, чтобы мы постоянно работали с положительным числом, а уже потом при необходимости перевели его в отрицательное.</li>
56 <ul><li><strong>Знак числа</strong>указывает, какое это число: положительное или отрицательное. Он нужен, чтобы мы постоянно работали с положительным числом, а уже потом при необходимости перевели его в отрицательное.</li>
57 <li><strong>Коэффициент</strong> - это основная часть десятичного числа, записанного обычно в диапазоне от 1 до 9. Но для чисел с плавающей точкой он находится в диапазоне от 0 до 1.</li>
57 <li><strong>Коэффициент</strong> - это основная часть десятичного числа, записанного обычно в диапазоне от 1 до 9. Но для чисел с плавающей точкой он находится в диапазоне от 0 до 1.</li>
58 <li><strong>Мантисса</strong> - это дробная часть коэффициента.</li>
58 <li><strong>Мантисса</strong> - это дробная часть коэффициента.</li>
59 <li><strong>Экспонента</strong> - это то, на что мы умножаем коэффициент.</li>
59 <li><strong>Экспонента</strong> - это то, на что мы умножаем коэффициент.</li>
60 </ul><p>Так, число 1.2 × 10-7 можно представить следующим образом:</p>
60 </ul><p>Так, число 1.2 × 10-7 можно представить следующим образом:</p>
61 <em>Изображение: Skillbox Media</em><p>Вот что мы получили:</p>
61 <em>Изображение: Skillbox Media</em><p>Вот что мы получили:</p>
62 <ul><li>+1 - знак числа (положительный),</li>
62 <ul><li>+1 - знак числа (положительный),</li>
63 <li>0.12 - мантисса,</li>
63 <li>0.12 - мантисса,</li>
64 <li>-8 - экспонента.</li>
64 <li>-8 - экспонента.</li>
65 </ul><p>Можно заметить, что мы сразу заменили коэффициент 1.2 на 0.12. Мантисса - 0.12.</p>
65 </ul><p>Можно заметить, что мы сразу заменили коэффициент 1.2 на 0.12. Мантисса - 0.12.</p>
66 <p>Число 10 называют основанием. Принято использовать его, потому что мы считаем всё в десятичной системе. Однако основание можно и поменять. Давайте представим число 0.12 × 10-8 в виде числа с основанием 5.</p>
66 <p>Число 10 называют основанием. Принято использовать его, потому что мы считаем всё в десятичной системе. Однако основание можно и поменять. Давайте представим число 0.12 × 10-8 в виде числа с основанием 5.</p>
67 <em>Изображение: Skillbox Media</em><p>Мантисса стала более устрашающей, но заметьте, что экспонента (то есть степень) не поменялась. И это абсолютно нормально, ведь мы применяли базовые правила умножения.</p>
67 <em>Изображение: Skillbox Media</em><p>Мантисса стала более устрашающей, но заметьте, что экспонента (то есть степень) не поменялась. И это абсолютно нормально, ведь мы применяли базовые правила умножения.</p>
68 <p>Почему не поменялась экспонента? Следите за руками :) Сначала мы разбиваем число 10 на множители - 5 и 2, а раз у исходного числа была степень -8, то у нас будут множители 5-8 и 2-8.</p>
68 <p>Почему не поменялась экспонента? Следите за руками :) Сначала мы разбиваем число 10 на множители - 5 и 2, а раз у исходного числа была степень -8, то у нас будут множители 5-8 и 2-8.</p>
69 <p>Теперь давайте перейдём к двоичному представлению. В нём основанием будет число 2, потому что это эквивалент числу 10 в двоичной системе. А мантисса будет точно так же лежать в диапазоне от 0 до 1 (не включительно). Поэтому всё, что меняется, - это основание.</p>
69 <p>Теперь давайте перейдём к двоичному представлению. В нём основанием будет число 2, потому что это эквивалент числу 10 в двоичной системе. А мантисса будет точно так же лежать в диапазоне от 0 до 1 (не включительно). Поэтому всё, что меняется, - это основание.</p>
70 <p>Выглядеть десятичное число 0.12 × 10-8 в двоичном представлении будет вот так:</p>
70 <p>Выглядеть десятичное число 0.12 × 10-8 в двоичном представлении будет вот так:</p>
71 <em>Изображение: Skillbox Media</em><p>Научная нотация - это тот принцип, по которому строится двоичное представление десятичных чисел в компьютерах. Теперь давайте разбираться, что за стандарт IEEE 754 и как он работает.</p>
71 <em>Изображение: Skillbox Media</em><p>Научная нотация - это тот принцип, по которому строится двоичное представление десятичных чисел в компьютерах. Теперь давайте разбираться, что за стандарт IEEE 754 и как он работает.</p>
72 <p>Стандарт IEEE 754 - это набор правил, которые описывают, как вещественные числа представляются в компьютере. Этот формат стал самым распространённым в программировании, когда дело доходит до арифметики чисел с плавающей точкой.</p>
72 <p>Стандарт IEEE 754 - это набор правил, которые описывают, как вещественные числа представляются в компьютере. Этот формат стал самым распространённым в программировании, когда дело доходит до арифметики чисел с плавающей точкой.</p>
73 <p>Числа представляются фиксированным количеством битов, каждый из которых отвечает своим задачам. В IEEE 754 обычно используют 32 бита. Они делятся на всё те же категории: один знаковый бит, 7 битов для экспоненты (то, на что мы умножаем мантиссу) и 24 бита для мантиссы (она выражает точность числа).</p>
73 <p>Числа представляются фиксированным количеством битов, каждый из которых отвечает своим задачам. В IEEE 754 обычно используют 32 бита. Они делятся на всё те же категории: один знаковый бит, 7 битов для экспоненты (то, на что мы умножаем мантиссу) и 24 бита для мантиссы (она выражает точность числа).</p>
74 <em>Изображение: Skillbox Media</em><p>Чтобы получить из этого представления десятичное число, используют следующую формулу:</p>
74 <em>Изображение: Skillbox Media</em><p>Чтобы получить из этого представления десятичное число, используют следующую формулу:</p>
75 <em>Изображение: Skillbox Media</em><p>Здесь З - это знаковый бит, М - мантисса, Э - экспонента. А ещё у нас появилось смещение. Оно необходимо, чтобы экспонента могла принимать положительные и отрицательные значения, и в стандарте IEEE 754 представляет собой константу - число 127.</p>
75 <em>Изображение: Skillbox Media</em><p>Здесь З - это знаковый бит, М - мантисса, Э - экспонента. А ещё у нас появилось смещение. Оно необходимо, чтобы экспонента могла принимать положительные и отрицательные значения, и в стандарте IEEE 754 представляет собой константу - число 127.</p>
76 <p>Если без смещения экспонента может принимать значения от 0 до 255, то со смещением от -127 до 128. Это нужно, чтобы представлять маленькие числа.</p>
76 <p>Если без смещения экспонента может принимать значения от 0 до 255, то со смещением от -127 до 128. Это нужно, чтобы представлять маленькие числа.</p>
77 <p>Чтобы вычислить мантиссу, мы должны добавить к ней слева единицу и после неё поставить точку, как будто это число с фиксированной точкой. А затем вычислить это число:</p>
77 <p>Чтобы вычислить мантиссу, мы должны добавить к ней слева единицу и после неё поставить точку, как будто это число с фиксированной точкой. А затем вычислить это число:</p>
78 <em>Изображение: Skillbox Media</em><p>Получили наше число 1.23, но не совсем. То, что вы видите, называется приближением двоичных чисел к десятичным. Если бы у нас было бесконечное количество битов, то мы смогли бы довольно точно представить число 1.23 в двоичной системе, и оно получило бы вид: 1.2300000000000000000000000000000001. Что уже неплохое приближение. Но так как у нас ограниченное число битов, приходится идти на округление.</p>
78 <em>Изображение: Skillbox Media</em><p>Получили наше число 1.23, но не совсем. То, что вы видите, называется приближением двоичных чисел к десятичным. Если бы у нас было бесконечное количество битов, то мы смогли бы довольно точно представить число 1.23 в двоичной системе, и оно получило бы вид: 1.2300000000000000000000000000000001. Что уже неплохое приближение. Но так как у нас ограниченное число битов, приходится идти на округление.</p>
79 <p>Теперь давайте подставим все числа в формулу:</p>
79 <p>Теперь давайте подставим все числа в формулу:</p>
80 <em>Изображение: Skillbox Media</em><p>Всё сходится. Попробуем перевести ещё одно число в десятичную систему. На этот раз двоичное число будет таким:</p>
80 <em>Изображение: Skillbox Media</em><p>Всё сходится. Попробуем перевести ещё одно число в десятичную систему. На этот раз двоичное число будет таким:</p>
81 <p>0 10000000 11100000000000000000000</p>
81 <p>0 10000000 11100000000000000000000</p>
82 <p>Пройдём все те же шаги:</p>
82 <p>Пройдём все те же шаги:</p>
83 <ul><li>знаковый бит - 0;</li>
83 <ul><li>знаковый бит - 0;</li>
84 <li>экспонента - 128;</li>
84 <li>экспонента - 128;</li>
85 <li>мантисса - 1.875.</li>
85 <li>мантисса - 1.875.</li>
86 </ul><p>Теперь подставляем в формулу:</p>
86 </ul><p>Теперь подставляем в формулу:</p>
87 <em>Изображение: Skillbox Media</em><p>Получили число 3.75 в десятичной записи.</p>
87 <em>Изображение: Skillbox Media</em><p>Получили число 3.75 в десятичной записи.</p>
88 <p>Мы узнали, как числа с плавающей точкой хранятся в памяти компьютера, какие биты за что отвечают и как происходит преобразование из стандарта IEEE 754 в десятичные числа. Теперь давайте узнаем, какие у них есть нюансы, о которых точно нужно знать.</p>
88 <p>Мы узнали, как числа с плавающей точкой хранятся в памяти компьютера, какие биты за что отвечают и как происходит преобразование из стандарта IEEE 754 в десятичные числа. Теперь давайте узнаем, какие у них есть нюансы, о которых точно нужно знать.</p>
89 <p>Числа с плавающей точкой имеют два нуля (положительный и отрицательный), две бесконечности (положительную и отрицательную) и неопределённость. И всё это нужно, чтобы правильнее считать числа.</p>
89 <p>Числа с плавающей точкой имеют два нуля (положительный и отрицательный), две бесконечности (положительную и отрицательную) и неопределённость. И всё это нужно, чтобы правильнее считать числа.</p>
90 <p><strong>Два нуля.</strong>В стандарте IEEE 754 существуют два нуля - положительный и отрицательный. Они нужны, чтобы компьютер мог различать значения, которые близки к нулю, но имеющие разные знаки. Это важно при умножении и делении.</p>
90 <p><strong>Два нуля.</strong>В стандарте IEEE 754 существуют два нуля - положительный и отрицательный. Они нужны, чтобы компьютер мог различать значения, которые близки к нулю, но имеющие разные знаки. Это важно при умножении и делении.</p>
91 <p>Например, представьте, что у банка есть финансовое приложение, которое работает с очень маленькими процентными ставками, такими как 10-15. Если бы у нас не было двух нулей, то при округлении мы бы получали неточные значения. Мы бы не смогли знать, отрицательная ставка у клиента или положительная, а это бы влияло на то, сколько он будет платить денег, что очень важно для него.</p>
91 <p>Например, представьте, что у банка есть финансовое приложение, которое работает с очень маленькими процентными ставками, такими как 10-15. Если бы у нас не было двух нулей, то при округлении мы бы получали неточные значения. Мы бы не смогли знать, отрицательная ставка у клиента или положительная, а это бы влияло на то, сколько он будет платить денег, что очень важно для него.</p>
92 <p>В стандарте IEEE 754 эти два нуля записываются так:</p>
92 <p>В стандарте IEEE 754 эти два нуля записываются так:</p>
93 Положительный ноль<em>Изображение: Skillbox Media</em>Отрицательный ноль<em>Изображение: Skillbox Media</em><p>Экспонента и мантисса должны содержать все нули, а знаковый бит будет указывать, какой мы имеем ноль: положительный или отрицательный.</p>
93 Положительный ноль<em>Изображение: Skillbox Media</em>Отрицательный ноль<em>Изображение: Skillbox Media</em><p>Экспонента и мантисса должны содержать все нули, а знаковый бит будет указывать, какой мы имеем ноль: положительный или отрицательный.</p>
94 <p><strong>Две бесконечности.</strong>Они напрямую связаны с двумя нулями. На уроках математики вам могли говорить, что делить на ноль нельзя, но это не совсем так. Делить на ноль можно, просто мы будем получать бесконечность, с которой не очень удобно работать.</p>
94 <p><strong>Две бесконечности.</strong>Они напрямую связаны с двумя нулями. На уроках математики вам могли говорить, что делить на ноль нельзя, но это не совсем так. Делить на ноль можно, просто мы будем получать бесконечность, с которой не очень удобно работать.</p>
95 <p>У бесконечности есть два типа: положительная бесконечность и отрицательная бесконечность. Чтобы получить положительную, нужно положительное число поделить на положительный ноль или отрицательное число на отрицательный ноль:</p>
95 <p>У бесконечности есть два типа: положительная бесконечность и отрицательная бесконечность. Чтобы получить положительную, нужно положительное число поделить на положительный ноль или отрицательное число на отрицательный ноль:</p>
96 <em>Изображение: Skillbox Media</em><p>Отрицательную бесконечность можно получить похожим образом, только если поделить отрицательное число на положительный ноль или положительное число на отрицательный ноль:</p>
96 <em>Изображение: Skillbox Media</em><p>Отрицательную бесконечность можно получить похожим образом, только если поделить отрицательное число на положительный ноль или положительное число на отрицательный ноль:</p>
97 <em>Изображение: Skillbox Media</em><p>Чтобы понять, где и когда применяют бесконечности, нужно обращаться к математическому анализу, но это сложная тема, которую мы не будем затрагивать. Давайте просто посмотрим, как выглядят бесконечности в виде двоичной записи стандарта IEEE 754:</p>
97 <em>Изображение: Skillbox Media</em><p>Чтобы понять, где и когда применяют бесконечности, нужно обращаться к математическому анализу, но это сложная тема, которую мы не будем затрагивать. Давайте просто посмотрим, как выглядят бесконечности в виде двоичной записи стандарта IEEE 754:</p>
98 Положительная бесконечность<em>Изображение: Skillbox Media</em>Отрицательная бесконечность<em>Изображение: Skillbox Media</em><p>В бесконечностях экспонента всегда должна состоять из единиц, а мантисса - из нулей. При этом знаковый бит указывает, какая это бесконечность: положительная или отрицательная.</p>
98 Положительная бесконечность<em>Изображение: Skillbox Media</em>Отрицательная бесконечность<em>Изображение: Skillbox Media</em><p>В бесконечностях экспонента всегда должна состоять из единиц, а мантисса - из нулей. При этом знаковый бит указывает, какая это бесконечность: положительная или отрицательная.</p>
99 <p><strong>Неопределённость.</strong>В математике есть понятие неопределённости. Это когда мы делим что-то на что-то и не знаем, какой результат получили. Звучит странно: как это мы можем не знать результат? Но давайте на примерах.</p>
99 <p><strong>Неопределённость.</strong>В математике есть понятие неопределённости. Это когда мы делим что-то на что-то и не знаем, какой результат получили. Звучит странно: как это мы можем не знать результат? Но давайте на примерах.</p>
100 <p>Что мы получим, если поделим ноль на ноль, бесконечность на бесконечность, бесконечность на ноль или ноль на бесконечность? Никто не знает. Поэтому математики говорят, что мы получим неопределённость. А в стандарте IEEE 754 вводят понятие Not-a-Number - NaN. Выглядит оно так:</p>
100 <p>Что мы получим, если поделим ноль на ноль, бесконечность на бесконечность, бесконечность на ноль или ноль на бесконечность? Никто не знает. Поэтому математики говорят, что мы получим неопределённость. А в стандарте IEEE 754 вводят понятие Not-a-Number - NaN. Выглядит оно так:</p>
101 <em>Изображение: Skillbox Media</em><p>Неопределённость очень похожа на бесконечность, но главное её отличие в том, что в числе NaN должен быть хотя бы один ненулевой бит в мантиссе.</p>
101 <em>Изображение: Skillbox Media</em><p>Неопределённость очень похожа на бесконечность, но главное её отличие в том, что в числе NaN должен быть хотя бы один ненулевой бит в мантиссе.</p>
102 <p>Стандарт IEEE 754 поддерживает два вида вещественных чисел: нормализованные и денормализованные. Нормализованные числа нужны, чтобы представлять очень большие значения, а денормализованные - очень маленькие, которые близки к нулю.</p>
102 <p>Стандарт IEEE 754 поддерживает два вида вещественных чисел: нормализованные и денормализованные. Нормализованные числа нужны, чтобы представлять очень большие значения, а денормализованные - очень маленькие, которые близки к нулю.</p>
103 <p><strong>Нормализованные числа.</strong>Они нужны, чтобы хранить и обрабатывать значения с максимально возможной точностью, что может быть критическим для некоторых приложений. Ещё для нормализованных чисел нужно меньше места в памяти.</p>
103 <p><strong>Нормализованные числа.</strong>Они нужны, чтобы хранить и обрабатывать значения с максимально возможной точностью, что может быть критическим для некоторых приложений. Ещё для нормализованных чисел нужно меньше места в памяти.</p>
104 <p>Если говорить просто, нормализованные числа - это научная нотация чисел. Например, чтобы записать число 123 в научной нотации, нужно привести его к такому виду: 1.23 × 102. Это и будет нормализованным числом. В нём коэффициент (число 1.23) должен находиться в диапазоне от 1 до 9.</p>
104 <p>Если говорить просто, нормализованные числа - это научная нотация чисел. Например, чтобы записать число 123 в научной нотации, нужно привести его к такому виду: 1.23 × 102. Это и будет нормализованным числом. В нём коэффициент (число 1.23) должен находиться в диапазоне от 1 до 9.</p>
105 <p>Чтобы отличать нормализованные числа, в стандарте IEEE 754 первый бит мантиссы делают равным единице. И тогда число принимает следующий вид:</p>
105 <p>Чтобы отличать нормализованные числа, в стандарте IEEE 754 первый бит мантиссы делают равным единице. И тогда число принимает следующий вид:</p>
106 Число 59 в нормализованном виде<em>Изображение: Skillbox Media</em><p>Удобство такого метода в том, что нам нужно хранить меньше битов в памяти, потому что первый бит мантиссы всегда равен единице. А также у нормализованных чисел гораздо больше диапазон значений.</p>
106 Число 59 в нормализованном виде<em>Изображение: Skillbox Media</em><p>Удобство такого метода в том, что нам нужно хранить меньше битов в памяти, потому что первый бит мантиссы всегда равен единице. А также у нормализованных чисел гораздо больше диапазон значений.</p>
107 <p>Но при этом возникает другая проблема: если число близко к нулю, то мы не можем представить его с нужной нам точностью. Это число просто пропадёт из нашего вида, потому что компьютер округлит его до нуля. Поэтому работать с очень маленькими значениями в нормализованном виде не получится.</p>
107 <p>Но при этом возникает другая проблема: если число близко к нулю, то мы не можем представить его с нужной нам точностью. Это число просто пропадёт из нашего вида, потому что компьютер округлит его до нуля. Поэтому работать с очень маленькими значениями в нормализованном виде не получится.</p>
108 <p><strong>Денормализованные числа.</strong>Чтобы решить проблему округления при близких к нулю значениях, используют денормализованные числа. Они менее эффективны, так как нужно хранить больше битов в памяти, но при этом более точны.</p>
108 <p><strong>Денормализованные числа.</strong>Чтобы решить проблему округления при близких к нулю значениях, используют денормализованные числа. Они менее эффективны, так как нужно хранить больше битов в памяти, но при этом более точны.</p>
109 <p>Если коэффициент нормализованных чисел принимает значения от 1 до 9, то у денормализованных - от 0 до 1, не включая последнюю. А первый бит мантиссы у таких чисел всегда равен нулю. Поэтому двоичная запись будет выглядеть так:</p>
109 <p>Если коэффициент нормализованных чисел принимает значения от 1 до 9, то у денормализованных - от 0 до 1, не включая последнюю. А первый бит мантиссы у таких чисел всегда равен нулю. Поэтому двоичная запись будет выглядеть так:</p>
110 Число 2.5 × 10-15 в денормализованном виде<em>Изображение: Skillbox Media</em><p>Денормализованные числа могут привести к потерям в точности во время математических операций, что само по себе приводит к нестабильности вычислений - а это очень плохо.</p>
110 Число 2.5 × 10-15 в денормализованном виде<em>Изображение: Skillbox Media</em><p>Денормализованные числа могут привести к потерям в точности во время математических операций, что само по себе приводит к нестабильности вычислений - а это очень плохо.</p>
111 <p>Некоторые системы предпочитают обращаться с денормализованными числами очень просто: считать, что они все равны нулю. Другие - используют специальные способы обработки таких значений. Но все они неэффективны, потому что компьютеры сами по себе не умеют с ними взаимодействовать.</p>
111 <p>Некоторые системы предпочитают обращаться с денормализованными числами очень просто: считать, что они все равны нулю. Другие - используют специальные способы обработки таких значений. Но все они неэффективны, потому что компьютеры сами по себе не умеют с ними взаимодействовать.</p>
112 <p>Интересно заметить, что граница между нормализованными и денормализованными числами лежит ровно на числе 0.75.</p>
112 <p>Интересно заметить, что граница между нормализованными и денормализованными числами лежит ровно на числе 0.75.</p>
113 <p>Выше мы рассматривали привычные числа с плавающей точкой. Они состоят из 32 битов: одного знакового бита, восьми для экспоненты и 23 для мантиссы. Этот стандарт называется одинарной точностью и является самым распространённым форматом среди вещественных чисел.</p>
113 <p>Выше мы рассматривали привычные числа с плавающей точкой. Они состоят из 32 битов: одного знакового бита, восьми для экспоненты и 23 для мантиссы. Этот стандарт называется одинарной точностью и является самым распространённым форматом среди вещественных чисел.</p>
114 <p>В разных языках программирования есть свои представления десятичных чисел, и в некоторых они суперточные. Например, в Java существуют типы BigInteger и BigDecimal, которые, по сути, не ограничивают размер числа. Такая переменная может хранить и 32 бита, и 302 бита. Но, конечно же, такой размах влияет на производительность, потому что хранятся эти числа как строки.</p>
114 <p>В разных языках программирования есть свои представления десятичных чисел, и в некоторых они суперточные. Например, в Java существуют типы BigInteger и BigDecimal, которые, по сути, не ограничивают размер числа. Такая переменная может хранить и 32 бита, и 302 бита. Но, конечно же, такой размах влияет на производительность, потому что хранятся эти числа как строки.</p>
115 <p>Одинарная точность может представить числа в диапазоне от -3.40282347 × 1038 до +3.40282347 × 1038. И сама точность составляет семь знаков после точки. Этот формат часто используют в компьютерной графике, научном моделировании и других приложениях, которым нужен баланс между диапазоном значений и точностью.</p>
115 <p>Одинарная точность может представить числа в диапазоне от -3.40282347 × 1038 до +3.40282347 × 1038. И сама точность составляет семь знаков после точки. Этот формат часто используют в компьютерной графике, научном моделировании и других приложениях, которым нужен баланс между диапазоном значений и точностью.</p>
116 <p>Кроме одинарной точности, есть ещё и двойная. Такие числа состоят из 64 битов, из которых один принадлежит знаку, 11 - экспоненте, 52 - мантиссе. Доступный диапазон значительно шире: от -1.7976931348623157 × 10308 до +1.7976931348623157 × 10308. А точность уже составляет 15-17 чисел после запятой.</p>
116 <p>Кроме одинарной точности, есть ещё и двойная. Такие числа состоят из 64 битов, из которых один принадлежит знаку, 11 - экспоненте, 52 - мантиссе. Доступный диапазон значительно шире: от -1.7976931348623157 × 10308 до +1.7976931348623157 × 10308. А точность уже составляет 15-17 чисел после запятой.</p>
117 <p>Числа с двойной точностью используют там, где важна высокая точность. Например, их применяют для научных и инженерных вычислений, в которых допустить ошибку бывает критично. Но это всё усложняется большими ресурсными тратами - в памяти и компьютерных мощностях.</p>
117 <p>Числа с двойной точностью используют там, где важна высокая точность. Например, их применяют для научных и инженерных вычислений, в которых допустить ошибку бывает критично. Но это всё усложняется большими ресурсными тратами - в памяти и компьютерных мощностях.</p>
118 <p>Мы разобрали, как устроены и как работают числа с плавающей точкой. Это тема гораздо шире и глубже, а её изучение может занять не один день. Поэтому давайте подведём итог и перечислим, что можно вынести из этой статьи:</p>
118 <p>Мы разобрали, как устроены и как работают числа с плавающей точкой. Это тема гораздо шире и глубже, а её изучение может занять не один день. Поэтому давайте подведём итог и перечислим, что можно вынести из этой статьи:</p>
119 <ul><li>Числа с плавающей точкой - это приближённое представление вещественных чисел в программировании. Все правила их представления записаны в стандарте IEEE 754.</li>
119 <ul><li>Числа с плавающей точкой - это приближённое представление вещественных чисел в программировании. Все правила их представления записаны в стандарте IEEE 754.</li>
120 <li>Этот стандарт нужен, чтобы разные компьютерные архитектуры могли одинаково удобно и эффективно работать с вещественными числами.</li>
120 <li>Этот стандарт нужен, чтобы разные компьютерные архитектуры могли одинаково удобно и эффективно работать с вещественными числами.</li>
121 <li>Числа с плавающей точкой бывают с одинарной точностью и двойной. Числа с одинарной точностью состоят из 32 битов: одного знакового бита, восьми битов для экспоненты и 23 битов для мантиссы. Числа с двойной точностью - из 64 битов: одного знакового бита, 11 битов для экспоненты и 52 битов для мантиссы.</li>
121 <li>Числа с плавающей точкой бывают с одинарной точностью и двойной. Числа с одинарной точностью состоят из 32 битов: одного знакового бита, восьми битов для экспоненты и 23 битов для мантиссы. Числа с двойной точностью - из 64 битов: одного знакового бита, 11 битов для экспоненты и 52 битов для мантиссы.</li>
122 <li>В стандарте IEEE 754 есть специальные значения, которые нужны для представления положительного и отрицательного нуля, бесконечностей и неопределённости.</li>
122 <li>В стандарте IEEE 754 есть специальные значения, которые нужны для представления положительного и отрицательного нуля, бесконечностей и неопределённости.</li>
123 </ul><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
123 </ul><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>