что такое плавающая запятая простыми словами

Наглядное объяснение чисел с плавающей запятой

что такое плавающая запятая простыми словами. 277c3b3c59830784ca7216063cf60f52. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-277c3b3c59830784ca7216063cf60f52. картинка что такое плавающая запятая простыми словами. картинка 277c3b3c59830784ca7216063cf60f52. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

При написании книги Game Engine Black Book: Wolfenstein 3D я хотел наглядно показать, насколько велики были проблемы при работе без плавающей запятой. Мои попытки разобраться в числах с плавающей запятой при помощи каноничных статей мозг воспринимал в штыки. Я начал искать другой способ. Что-нибудь, далёкое от что такое плавающая запятая простыми словами. 185bbae8c3b7f000517f7294785b185d. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-185bbae8c3b7f000517f7294785b185d. картинка что такое плавающая запятая простыми словами. картинка 185bbae8c3b7f000517f7294785b185d. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.и их загадочных экспонент с мантиссами. Может быть, в виде рисунка, потому что их мой мозг воспринимает проще.

В результате я написал эту статью и решил добавить её в книгу. Не буду утверждать, что это моё изобретение, но пока мне не приходилось видеть такого объяснения чисел с плавающей запятой. Надеюсь, статья поможет тем, у кого, как и у меня, аллергия на математические обозначения.

Как обычно объясняют числа с плавающей запятой

Цитирую Дэвида Голдберта (David Goldbert):

Для многих людей арифметика с плавающей запятой кажется каким-то тайным знанием.

Полностью с ним согласен. Однако важно понимать принципы её работы, чтобы полностью осознать её полезность при программировании 3D-движка. В языке C значения с плавающей запятой — это 32-битные контейнеры, соответствующие стандарту IEEE 754. Они предназначены для хранения и выполнения операций над аппроксимациями вещественных чисел. Пока я видел только такое их объяснение. 32 бита разделены на три части:

что такое плавающая запятая простыми словами. 7a57b282968af9e41765d00139996ae6. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-7a57b282968af9e41765d00139996ae6. картинка что такое плавающая запятая простыми словами. картинка 7a57b282968af9e41765d00139996ae6. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.
Три части числа с плавающей запятой.

Пока всё нормально. Пойдём дальше. Способ интерпретации чисел обычно объясняется с помощью такой формулы:

что такое плавающая запятая простыми словами. 5c3574f9536e36dd554068bc07fdcf97. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-5c3574f9536e36dd554068bc07fdcf97. картинка что такое плавающая запятая простыми словами. картинка 5c3574f9536e36dd554068bc07fdcf97. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

Именно это объяснение чисел с плавающей запятой все ненавидят.

И здесь я обычно начинаю терять терпение. Возможно, у меня аллергия на математическую нотацию, но когда я это читаю, в моём мозгу ничего не «щёлкает». Такое объяснение похоже на способ рисования совы:

что такое плавающая запятая простыми словами. ffde28bed869f46a86ffa35e0dd36ef6. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-ffde28bed869f46a86ffa35e0dd36ef6. картинка что такое плавающая запятая простыми словами. картинка ffde28bed869f46a86ffa35e0dd36ef6. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

Другой способ объяснения

Хоть это изложение и верно, такой способ объяснения чисел с плавающей запятой обычно не даёт нам никакого понимания. Я виню эту ужасную запись в том, что она разочаровала тысячи программистов, испугала их до такой степени, что они больше никогда не пытались понять, как же на самом деле работают вычисления с плавающей запятой. К счастью, их можно объяснить иначе. Воспринимайте экспоненту как окно (Window) или интервал между двумя соседними целыми степенями двойки. Мантиссу воспринимайте как смещение (Offset) в этом окне.

что такое плавающая запятая простыми словами. ea77b7a9579e487696cb844f48c7e366. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-ea77b7a9579e487696cb844f48c7e366. картинка что такое плавающая запятая простыми словами. картинка ea77b7a9579e487696cb844f48c7e366. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.
Три части числа с плавающей запятой.

Окно сообщает нам, между какими двумя последовательными степенями двойки будет число: [0,1], [1,2], [2,4], [4,8] и так далее (вплоть до [что такое плавающая запятая простыми словами. c4627726e5e2f775190899860d647c24. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-c4627726e5e2f775190899860d647c24. картинка что такое плавающая запятая простыми словами. картинка c4627726e5e2f775190899860d647c24. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.,что такое плавающая запятая простыми словами. 048e69f54fe928d300212ed394850655. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-048e69f54fe928d300212ed394850655. картинка что такое плавающая запятая простыми словами. картинка 048e69f54fe928d300212ed394850655. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.]. Смещение разделяет окно на что такое плавающая запятая простыми словами. 4111231fd1ce247f10cc8bbceb824746. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-4111231fd1ce247f10cc8bbceb824746. картинка что такое плавающая запятая простыми словами. картинка 4111231fd1ce247f10cc8bbceb824746. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.сегментов. С помощью окна и смещения можно аппроксимировать число. Окно — это отличный механизм защиты от выхода за границы. Достигнув максимума в окне (например, в [2,4]), можно «переплыть» вправо и представить число в пределах следующего окна (например, [4,8]). Ценой этого будет только небольшое снижение точности, потому что окно становится в два раза больше.

Викторина: сколько точности теряется, когда окно закрывает больший интервал? Давайте возьмём пример с окном [0,1], в котором 8388608 смещений накладываются на интервал размером 1, что даёт нам точность что такое плавающая запятая простыми словами. 9b14288c33ec3413c403031084bc86ba. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-9b14288c33ec3413c403031084bc86ba. картинка что такое плавающая запятая простыми словами. картинка 9b14288c33ec3413c403031084bc86ba. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.. В окне [2048,4096] 8388608 смещений накладываются на интервал что такое плавающая запятая простыми словами. 8f5ada68b6cf83abcb83b04484617e43. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-8f5ada68b6cf83abcb83b04484617e43. картинка что такое плавающая запятая простыми словами. картинка 8f5ada68b6cf83abcb83b04484617e43. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа., что даёт нам точность что такое плавающая запятая простыми словами. 245e0e6324cf123a1019f825642bbbb9. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-245e0e6324cf123a1019f825642bbbb9. картинка что такое плавающая запятая простыми словами. картинка 245e0e6324cf123a1019f825642bbbb9. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа..

На рисунке ниже показано, как кодируется число 6,1. Окно должно начинаться с 4 и заканчиваться следующей степенью двойки, т.е. 8. Смещение находится примерно посередине окна.

что такое плавающая запятая простыми словами. 2805802501f4fa66edcf49b4a50ddc12. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-2805802501f4fa66edcf49b4a50ddc12. картинка что такое плавающая запятая простыми словами. картинка 2805802501f4fa66edcf49b4a50ddc12. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.
Значение 6,1 аппроксимированное с помощью числа с плавающей запятой.

Давайте возьмём ещё один пример с подробным вычислением представлением в виде числа с плавающей точкой хорошо известного всем нам значения: 3,14.

что такое плавающая запятая простыми словами. 3b937226f3359ef2c9217e7e48f832ac. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-3b937226f3359ef2c9217e7e48f832ac. картинка что такое плавающая запятая простыми словами. картинка 3b937226f3359ef2c9217e7e48f832ac. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

Двоичное представление с плавающей точкой числа 3,14.

То есть значение 3,14 аппроксимируется как 3,1400001049041748046875.

Соответствующее значение в непонятной формуле:

что такое плавающая запятая простыми словами. a49916e578302f5b4c78000c2c8d0c4f. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-a49916e578302f5b4c78000c2c8d0c4f. картинка что такое плавающая запятая простыми словами. картинка a49916e578302f5b4c78000c2c8d0c4f. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

И, наконец, графическое представление с окном и смещением:

что такое плавающая запятая простыми словами. 31ab34fb70422239df4a7293f32d0452. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-31ab34fb70422239df4a7293f32d0452. картинка что такое плавающая запятая простыми словами. картинка 31ab34fb70422239df4a7293f32d0452. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

Окно и смещение числа 3,14.

Интересный факт: если модули операций с плавающей запятой были такими медленными, почему в языке C в результате использовали типы float и double? Ведь в машине, на которой изобретался язык (PDP-11), не было модуля операций с плавающей запятой! Дело в том, что производитель (DEC) пообещал Деннису Ритчи и Кену Томпсону, что в следующей модели он будет. Они были любителями астрономии и решили добавить в язык эти два типа.

Интересный факт: те, кому в 1991 году действительно нужен был аппаратный модуль операций с плавающей запятой, могли его купить. Единственными, кому он мог понадобиться в то время, были учёные (по крайней мере, так Intel понимала потребности рынка). На рынке они позиционировались как «математические сопроцессоры». Их производительность была средней, а цена огромной (200 долларов 1993 года — это 350 долларов в 2016 году.). В результате уровень продаж оказался посредственным.

Источник

Почти безопасные: пару слов о псевдо-нормальных числах с плавающей запятой

что такое плавающая запятая простыми словами. image loader. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-image loader. картинка что такое плавающая запятая простыми словами. картинка image loader. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

В этой статье описаны новые типы чисел с плавающей запятой, которые ничему не соответствуют в физическом мире. Числа, которые я называю псевдо-нормальными числами, могут создать проблемы для программистов, которые трудно отследить, и даже попали в печально известный список Common Vulnerabilities and Exposures (CVE).

Краткая предыстория: double IEEE-754

Практически каждый язык программирования реализует 64-битные double (числа с плавающей запятой двойной точности) с использованием формата IEEE-754. Формат определяет 64-битное хранилище, которое имеет один знаковый бит, 11 битов порядка/экспоненты (exponent bits) и 52 бита мантиссы (significand bits). Каждый битовый паттерн принадлежит одному единственному из этих типов чисел с плавающей запятой:

Нормальное число: в экспоненте установлен (в единицу) хотя бы один бит (но не все биты). Биты мантиссы и знака могут иметь любое значение.

Денормализованное/субнормальное (denormal) число: у экспоненты все биты сброшены (в ноль). Биты мантиссы и знака могут иметь любое значение.

Бесконечность (Infinity): у экспоненты установлены все биты. В мантиссе все биты сброшены, а знаковый бит может иметь любое значение.

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

Биты мантиссы описывают только дробную часть; для денормализованных чисел и нулей первый бит мантиссы (в оригинале “integer”) по соглашению равен нулю, а для всех остальных чисел он равен единице. Языки программирования идеально сопоставляют представления с этими категориями чисел. Не существует числа с плавающей запятой двойной точности, для которого, по крайней мере, не определена его классификация. Из-за широкого распространения можно в значительной степени полагаться на единообразное поведение на разных аппаратных платформах и средах выполнения.

Формат чисел с плавающей запятой двойной расширенной точности от Intel

Раздел 4.2 в руководстве разработчика программного обеспечения для архитектур Intel 64 и IA-32 определяется формат числа с плавающей запятой двойной расширенной точности как 80-битное значение со схемой, показанной на рисунке 1.

что такое плавающая запятая простыми словами. image loader. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-image loader. картинка что такое плавающая запятая простыми словами. картинка image loader. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.Рисунок 1: Макет формата числа с плавающей запятой двойной расширенной точности от Intel.

Учитывая это определение, наши надежные классификации чисел, на которые мы полагаемся, сопоставляются с форматом long-double следующим образом:

Нормальное число: у экспоненты установлен хотя бы один бит (но не все биты). Биты мантиссы и знака могут иметь любое значение. Первый бит мантиссы (integer bit) установлен в единицу.

Денормализованное число: у экспоненты все биты сброшены. Биты мантиссы и знака могут иметь любое значение. Первый бит мантиссы сброшен в ноль.

Бесконечность: у экспоненты установлены все биты. В мантиссе все биты сброшены, а знаковый бит может иметь любое значение. Первый бит мантиссы установлен в единицу.

Неопределенность (NaN): у экспоненты установлены все биты. Мантисса имеет по крайней мере один установленный бит, а знаковый бит может иметь любое значение. Первый бит мантиссы установлен в единицу.

Ноль: у экспоненты и мантиссы все биты сброшены. Знаковый бит может иметь любое значение. Первый бит мантиссы сброшен в ноль.

Кризис идентичности

Внимательный наблюдатель может задать два очень разумных вопроса:

Что, если у нормального числа, бесконечности или NaN первый бит мантиссы сброшен в ноль?

Что, если у денормализованного числа первый бит мантиссы установлен в единицу?

С этими вопросами вы откроете для себя новый набор чисел. Поздравляю!

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

Как классифицировать псевдо-нормальные числа?

Изменение среды программирования для введения нового класса чисел не является стоящим решениям ни для какой архитектуры, так что об этом не может быть и речи. Отнесение этих чисел к существующим классам может зависеть от того, к какому классу они относятся. В качестве альтернативы, мы могли бы коллективно рассматривать их как NaN (в частности, сигнальный NaN), потому что, как и сигнальный NaN, работа с ними генерирует исключение недопустимой операции.

Неопределенное поведение?

Здесь возникает актуальный вопрос, должны ли мы вообще об этом думать. Стандарт C, например, в разделе 6.2.6 Представления типов, утверждает, что «Некоторые определенные представления объектов не обязательно должны представлять значение типа объекта», что соответствует нашей ситуации. FPU никогда не будет генерировать эти представления для типа long double, поэтому можно утверждать, что передача этих представлений в long double не определена. Это один из способов ответить на вопрос о классификации, но он, по сути, мешает пользователю понять спецификацию оборудования. Это подразумевает, что каждый раз, когда пользователь читает long double из двоичного файла или сети, ему необходимо проверить, действительно ли представление соответствует базовой архитектуре. Это то, что функция fpclassify и ей подобные должны делать, но, к сожалению, они этого не делают.

Если есть много ответов, вы получите много ответов

Почти (но не полностью) безопасные

Реализация isnanl в glibc предполагает, что он всегда получает правильно отформатированный long double. Это не является необоснованным предположением, но оно возлагает на каждого программиста ответственность по проверке двоичных данных long double, считываемых из файлов или сети, перед их передачей в isnanl, который, по иронии судьбы, является функцией проверки.

Эти предположения привели к CVE-2020-10029 и CVE-2020-29573. В обоих этих CVE функции (тригонометрические функции в первом и семейство функций printf во втором) полагаются на допустимые входные данные и в конечном итоге приводят к потенциальным переполнениям стека. Мы исправили CVE-2020-10029, рассматривая псевдо-нормальные числа как NaN. Функции проверяют первый бит мантиссы и дают сбой, если он равен нулю.

Соглашение о решении

CVE побудили нас (сообщество инструментальных средств GNU) более серьезно поговорить о классификации этих чисел по отношению к интерфейсу библиотеки C. Мы обсудили это в сообществах glibc и GCC и согласились, что эти числа следует рассматривать как сигнальные NaN в контексте интерфейсов библиотеки C. Однако это не означает, что libm будет стремиться последовательно обрабатывать эти числа как NaN внутренне или обеспечивать исчерпывающий охват. Цель не в том, чтобы определять поведение этих чисел; это только для того, чтобы сделать классификацию последовательной во всей цепочке инструментов. Что еще более важно, мы согласовали рекомендации в случаях, когда неправильная классификация этих чисел приводит к сбоям или проблемам с безопасностью.

Это, друзья, история ненормальных чисел, псевдо-NaN и псевдо-бесконечности. Я надеюсь, что вы никогда не столкнетесь с ними, но если столкнетесь, надеюсь, мы упростили для вас борьбу с ними.

Хотите узнать чем же все-таки язык С++ лучше других ЯП? Тогда приглашаю всех желающих зарегистрироваться на бесплатный интенсив, в рамках которого мы настроим свой http-сервер и разберем его что называется «от и до»; А во второй день произведем все необходимые замеры и сделаем наш сервер супер быстрым.

Источник

Запятая плавающая

Плавающая запятая — форма представления дробных чисел, в которой число хранится в форме мантиссы и показателя степени. При этом число с плавающей запятой имеет фиксированную относительную точность и изменяющуюся абсолютную. Наиболее часто используемое представление утверждено в стандарте IEEE 754. Реализация математических операций с числами с плавающей запятой в вычислительных системах может быть как аппаратная, так и программная.

Содержание

«Плавающая запятая» и «плавающая точка»

Так как в некоторых, преимущественно англоязычных и англофицированных, странах (см. подробный список Decimal separator (англ.) ) при записи чисел целая часть отделяется от дробной точкой, то в терминологии этих стран фигурирует название «плавающая точка» (floating point (англ.) ). Так как в России целая часть числа от дробной традиционно отделяется запятой, то для обозначения того же понятия используется термин «плавающая запятая».

Происхождение названия

Название «плавающая запятая» происходит от того, что запятая в позиционном представлении числа (десятичная запятая, или, для компьютеров, двоичная запятая — далее по тексту просто запятая) может быть помещена где угодно относительно цифр в строке. Это положение запятой указывается отдельно во внутреннем представлении. Таким образом, представление числа в форме с плавающей запятой может рассматриваться как компьютерная реализация экспоненциальной записи чисел.

Преимущество использования представления чисел в формате с плавающей запятой над представлением в формате с фиксированной запятой (и целыми числами) состоит в том, что можно использовать существенно больший диапазон значений при неизменной относительной точности. Например, в форме с фиксированной запятой число, занимающее 8 разрядов в целой части и 2 разряда после запятой, может быть представлено в виде 123456,78; 8765,43; 123,00 и так далее. В свою очередь, в формате с плавающей запятой (в тех же 8 разрядах) можно записать числа 1,2345678; 1234567,8; 0,000012345678; 12345678000000000 и так далее.

Скорость выполнения компьютером операций с числами, представленными в форме с плавающей запятой, измеряется в англ. FLOPS — число операций с плавающей запятой в секунду ),

Структура числа

Число с плавающей запятой состоит из:

Нормальная форма

Использование в вычислительных машинах

Краткий обзор

Существует несколько способов того, как строки из цифр могут представлять числа:

Запись числа в форме с плавающей запятой позволяет производить вычисления над широким диапазоном величин, сочетая фиксированное количество разрядов и точность. Например, в десятичной системе предоставления чисел с плавающей запятой (3 разряда) операцию умножения, которую мы бы записали как

в нормальной форме представляется в виде

(1,20 × 10 −1 ) × (1,20 × 10 −1 ) = (1,44 × 10 −2 ).

В формате с фиксированной запятой мы бы получили вынужденное округление

Мы потеряли крайний правый разряд числа, так как данный формат не позволяет запятой «плавать» по записи числа.

Диапазон чисел, представимых в формате с плавающей запятой

Диапазон чисел, которые можно записать данным способом, зависит от количества бит, отведённых для представления мантиссы и показателя. На обычной 32-битной вычислительной машине, использующей двойную точность (64 бита), мантисса составляет 52 бита + 1 знаковый, показатель — 11 бит. Таким образом получаем диапазон точности примерно от 4,94 × 10 −324 до 1.79 × 10 308 (от 2 −52 × 2 −1022 до

1 × 2 1024 ). Пара значений показателя зарезервирована для обеспечения возможности представления специальных чисел. К ним относятся значения бесконечность), получающихся в результате операций типа деления на ноль нуля, положительных и отрицательных чисел. Также сюда попадают денормализованные числа, у которых мантисса меньше единицы. В специализированных устройствах (например GPU) поддержка специальных чисел часто отсутствует. Существуют программные пакеты, в которых объём памяти выделенный под мантиссу и показатель задаётся программно, и ограничивается лишь объёмом доступной памяти ЭВМ.

Машинный эпсилон

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

Машинным эпсилоном называется наименьшее положительное число ε такое, что что такое плавающая запятая простыми словами. 84c94736f5fd07643d1d14a4681e46c8. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-84c94736f5fd07643d1d14a4681e46c8. картинка что такое плавающая запятая простыми словами. картинка 84c94736f5fd07643d1d14a4681e46c8. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.(знаком что такое плавающая запятая простыми словами. b71edd70fcad670e99a9912ba5e55d77. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-b71edd70fcad670e99a9912ba5e55d77. картинка что такое плавающая запятая простыми словами. картинка b71edd70fcad670e99a9912ba5e55d77. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.обозначено машинное сложение). Грубо говоря, числа a и b, соотносящиеся так, что что такое плавающая запятая простыми словами. 55240b060fdc716167ca22b9cf962b1d. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-55240b060fdc716167ca22b9cf962b1d. картинка что такое плавающая запятая простыми словами. картинка 55240b060fdc716167ca22b9cf962b1d. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа., машина не различает.

Источник

Что нужно знать про арифметику с плавающей запятой

что такое плавающая запятая простыми словами. 20096c9dd85a9a34da4a5b34f2af0a07. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-20096c9dd85a9a34da4a5b34f2af0a07. картинка что такое плавающая запятая простыми словами. картинка 20096c9dd85a9a34da4a5b34f2af0a07. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

В далекие времена, для IT-индустрии это 70-е годы прошлого века, ученые-математики (так раньше назывались программисты) сражались как Дон-Кихоты в неравном бою с компьютерами, которые тогда были размером с маленькие ветряные мельницы. Задачи ставились серьезные: поиск вражеских подлодок в океане по снимкам с орбиты, расчет баллистики ракет дальнего действия, и прочее. Для их решения компьютер должен оперировать действительными числами, которых, как известно, континуум, тогда как память конечна. Поэтому приходится отображать этот континуум на конечное множество нулей и единиц. В поисках компромисса между скоростью, размером и точностью представления ученые предложили числа с плавающей запятой (или плавающей точкой, если по-буржуйски).

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

1. Основы

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

Число с плавающей запятой состоит из набора отдельных разрядов, условно разделенных на знак, экспоненту порядок и мантиссу. Порядок и мантисса — целые числа, которые вместе со знаком дают представление числа с плавающей запятой в следующем виде:

что такое плавающая запятая простыми словами. image loader. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-image loader. картинка что такое плавающая запятая простыми словами. картинка image loader. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

Математически это записывается так:

Основание определяет систему счисления разрядов. Математически доказано, что числа с плавающей запятой с базой B=2 (двоичное представление) наиболее устойчивы к ошибкам округления, поэтому на практике встречаются только базы 2 и, реже, 10. Для дальнейшего изложения будем всегда полагать B=2, и формула числа с плавающей запятой будет иметь вид:

Что такое мантисса и порядок? Мантисса – это целое число фиксированной длины, которое представляет старшие разряды действительного числа. Допустим наша мантисса состоит из трех бит (|M|=3). Возьмем, например, число «5», которое в двоичной системе будет равно 1012. Старший бит соответствует 2 2 =4, средний (который у нас равен нулю) 2 1 =2, а младший 2 0 =1. Порядок – это степень базы (двойки) старшего разряда. В нашем случае E=2. Такие числа удобно записывать в так называемом «научном» стандартном виде, например «1.01e+2». Сразу видно, что мантисса состоит из трех знаков, а порядок равен двум.

Допустим мы хотим получить дробное число, используя те же 3 бита мантиссы. Мы можем это сделать, если возьмем, скажем, E=1. Тогда наше число будет равно

2 = 10 (в двоичной системе) = 1.000e+1 = 0.100e+2 = 0.010e+3. (E=1, E=2, E=3 соответственно)

Обратите внимание, что одно и то же число имеет несколько представлений. Это не удобно для оборудования, т.к. нужно учитывать множественность представлния при сравнении чисел и при выполнении над ними арифметических операций. Кроме того, это не экономично, поскольку число представлений — конечное, а повторения уменьшают множество чисел, которые вообще могут быть представлены. Поэтому уже в самых первых машинах начали использовать трюк, делая первый бит мантиссы всегда положительным. Такое предаставление назвали нормализованным.

что такое плавающая запятая простыми словами. image loader. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-image loader. картинка что такое плавающая запятая простыми словами. картинка image loader. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

Это экономит один бит, так как неявную единицу не нужно хранить в памяти, и обеспечивает уникальность представления числа. В нашем примере «2» имеет единственное нормализованное представление («1.000e+1»), а мантисса хранится в памяти как «000», т.к. старшая единица подразумевается неявно. Но в нормализованном представлении чисел возникает новая проблема — в такой форме невозможно представить ноль.

Строго говоря, нормализованное число имеет следующий вид:

Качество решения задач во многом зависит от выбора представления чисел с плавающей запятой. Мы плавно подошли к проблеме стандартизации такого представления.

2. Немного истории

В 60-е и 70-е годы не было единого стандарта представления чисел с плавающей запятой, способов округления, арифметических операций. В результате программы были крайне не портабельны. Но еще большей проблемой было то, что у разных компьютеров были свои «странности» и их нужно было знать и учитывать в программе. Например, разница двух не равных чисел возвращала ноль. В результате выражения «X=Y» и «X-Y=0» вступали в противоречие. Умельцы обходили эту проблему очень хитрыми трюками, например, делали присваивание «X=(X-X)+X» перед операциями умножения и деления, чтобы избежать проблем.

Инициатива создать единый стандарт для представления чисел с плавающей запятой подозрительно совпала с попытками в 1976 году компанией Intel разработать «лучшую» арифметику для новых сопроцессоров к 8086 и i432. За разработку взялись ученые киты в этой области, проф. Джон Палмер и Уильям Кэхэн. Последний в своем интервью высказал мнение, что серьезность, с которой Intel разрабатывала свою арифметику, заставила другие компании объединиться и начать процесс стандартизации.

Все были настроены серьезно, ведь очень выгодно продвинуть свою архитектуру и сделать ее стандартной. Свои предложения представили компании DEC, National Superconductor, Zilog, Motorola. Производители мейнфреймов Cray и IBM наблюдали со стороны. Компания Intel, разумеется, тоже представила свою новую арифметику. Авторами предложенной спецификации стали Уильям Кэхэн, Джероми Кунен и Гарольд Стоун и их предложение сразу прозвали «K-C-S».

Практически сразу же были отброшены все предложения, кроме двух: VAX от DEC и «K-C-S» от Intel. Спецификация VAX была значительно проще, уже была реализована в компьютерах PDP-11, и было понятно, как на ней получить максимальную производительность. С другой стороны в «K-C-S» содержалось много полезной функциональности, такой как «специальные» и «денормализованные» числа (подробности ниже).

В «K-C-S» все арифметические алгоритмы заданы строго и требуется, чтобы в реализации результат с ними совпадал. Это позволяет выводить строгие выкладки в рамках этой спецификации. Если раньше математик решал задачу численными методами и доказывал свойства решения, не было никакой гарантии, что эти свойства сохранятся в программе. Строгость арифметики «K-C-S» сделала возможным доказательство теорем, опираясь на арифметику с плавающей запятой.

Компания DEC сделала все, чтобы ее спецификацию сделали стандартом. Она даже заручилась поддержкой некоторых авторитетных ученых в том, что арифметика «K-C-S» в принципе не может достигнуть такой же производительности, как у DEC. Ирония в том, что Intel знала, как сделать свою спецификацию такой же производительной, но эти хитрости были коммерческой тайной. Если бы Intel не уступила и не открыла часть секретов, она бы не смогла сдержать натиск DEC.

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

3. Представление чисел с плавающей запятой сегодня

Разработчики «K-C-S» победили и теперь их детище воплотилось в стандарт IEEE754. Числа с плавающей запятой в нем представлены в виде знака (s), мантиссы (M) и порядка (E) следующим образом:

Замечание. В новом стандарте IEE754-2008 кроме чисел с основанием 2 присутствуют числа с основанием 10, так называемые десятичные (decimal) числа с плавающей запятой.

Чтобы не загромождать читателя чрезмерной информацией, которую можно найти в Википедии, рассмотрим только один тип данных, с одинарной точностью (float). Числа с половинной, двойной и расширенной точностью обладают теми же особенностями, но имеют другой диапазон порядка и мантиссы. В числах одинарной точности (float/single) порядок состоит из 8 бит, а мантисса – из 23. Эффективный порядок определяется как E-127. Например, число 0,15625 будет записано в памяти как

что такое плавающая запятая простыми словами. image loader. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-image loader. картинка что такое плавающая запятая простыми словами. картинка image loader. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.
Рисунок взят из Википедии

3.1 Специальные числа: ноль, бесконечность и неопределенность

Неопределенность или NaN (от not a number) – это представление, придуманное для того, чтобы арифметическая операция могла всегда вернуть какое-то не бессмысленное значение. В IEEE754 NaN представлен как число, в котором E=Emax+1, а мантисса не нулевая. Любая операция с NaN возвращает NaN. При желании в мантиссу можно записывать информацию, которую программа сможет интерпретировать. Стандартом это не оговорено и мантисса чаще всего игнорируется.

Вернемся к примеру. Наш Emin=-1. Введем новое значение порядка, E=-2, при котором числа являются денормализованными. В результате получаем новое представление чисел:

что такое плавающая запятая простыми словами. image loader. что такое плавающая запятая простыми словами фото. что такое плавающая запятая простыми словами-image loader. картинка что такое плавающая запятая простыми словами. картинка image loader. В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

Интервал от 0 до 0,5 заполняют денормализованные числа, что дает возможность не проваливаться в 0 рассмотренных выше примерах (0,5-0,25 и 1,5-1,25). Это сделало представление более устойчиво к ошибкам округления для чисел, близких к нулю.

Но роскошь использования денормализованного представления чисел в процессоре не дается бесплатно. Из-за того, что такие числа нужно обрабатывать по-другому во всех арифметических операциях, трудно сделать работу в такой арифметике эффективной. Это накладывает дополнительные сложности при реализации АЛУ в процессоре. И хоть денормализованные числа очень полезны, они не являются панацеей и за округлением до нуля все равно нужно следить. Поэтому эта функциональность стала камнем преткновения при разработке стандарта и встретила самое сильное сопротивление.

3.4 Очередность чисел в IEEE754

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

4.2 Неассоциативность арифметических операций

В арифметике с плавающей запятой правило (a*b)*c = a*(b*c) не выполняется для любых арифметических операций. Например,

Допустим у нас есть программа суммирования чисел.

Некоторые компиляторы по умолчанию могут переписать код для использования нескольких АЛУ одновременно (будем считать, что n делится на 2):

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

4.3 Числовые константы

Помните, что не все десятичные числа имеют двоичное представление с плавающей запятой. Например, число «0,2» будет представлено как «0,200000003» в одинарной точности. Соответственно, «0,2 + 0,2 ≈ 0,4». Абсолютная погрешность в отдельном
случае может и не высока, но если использовать такую константу в цикле, можем получить накопленную погрешность.

4.4 Выбор минимума из двух значений
4.5 Сравнение чисел

Очень распространенная ошибка при работе с float-ами возникает при проверке на равенство. Например,

Ошибка здесь, во-первых, в том, что 0,2 не имеет точного двоичного представления, а во-вторых 0,2 – это константа двойной точности, а переменная fValue – одинарной, и никакой гарантии о поведении этого сравнения нет.

Лучший, но все равно ошибочный способ, это сравнивать разницу с допустимой абсолютной погрешностью:

Недостаток такого подхода в том, что погрешность представления числа увеличивается с ростом самого этого числа. Так, если программа ожидает «10000», то приведенное равенство не будет выполняться для ближайшего соседнего числа (10000,000977). Это особенно актуально, если в программе имеется преобразование из одинарной точности в двойную.

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

5. Проверка полноты поддержки IEE754

Думаете, что если процессоры полностью соответствуют стандарту IEEE754, то любая программа, использующая стандартные типы данных (такие как float/double в Си), будет выдавать один и тот же результат на разных компьютерах? Ошибаетесь. На портабельность и соответствие стандарту влияет компилятор и опции оптимизации. Уильям Кэхэн написал программу на Си (есть версия и для Фортрана), которая позволяет проверить удовлетворяет ли связка «архитектура+компилятор+опции» IEEE754. Называется она «Floating point paranoia» и ее исходные тексты доступны для скачивания. Аналогичная программа доступна для GPU. Так, например, компилятор Intel (icc) по умолчанию использует «расслабленную» модель IEEE754, и в результате не все тесты выполняются. Опция «-fp-model precise» позволяет компилировать программу с точным соответствием стандарту. В компиляторе GCC есть опция «-ffast-math», использование которой приводит к несоответствию IEEE754.

Заключение

Напоследок поучительная история. Когда я работал над тестовым проектом на GPU, у меня была последовательная и параллельная версия одной программы. Сравнив время выполнения, я был очень обрадован, так как получил ускорение в 300 раз. Но позже оказалось, что вычисления на GPU «разваливались» и обращались в NaN, а работа с ними в GPU была быстрее, чем с обычными числами. Интересно было другое — одна и та же программа на эмуляторе GPU (на CPU) выдавала корректный результат, а на самом GPU – нет. Позже оказалось, что проблема была в том, что этот GPU не поддерживал полностью стандарт IEEE754 и прямой подход не сработал.

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *