Pull to refresh

Comments 54

В идеале, количество значащих цифр двоичной мантиссы числа должно быть равно количеству разрядов машинной мантиссы.
Не «равно», а «не больше».
И это всё очевидные вещи. Для кого эта статья? Какую цель она преследует? Это уже пятая (шестая?) статья «цикла». И в каждой статье речь всегда об одном и том же. Зачем?
Исправил. Речь идет о приближенных числах.
И в каждой статье речь всегда об одном и том же. Зачем?

Вы правы, речь идет об одном и том же — о числах с плавающей точкой. А статьи мои о том, что не существует особенной компьютерной арифметики. Существует классическая арифметика с определенными ограничениями, которые надо учитывать при решении арифметических задач на компьютере. И это не тавтология. В классическом труде David Goldberg «What Every Computer Scientist Should Know About Floating-Point Arithmetic» в представлении ЧПТ: b^p x M, утверждается, что знак умножить в этом выражении таковым не является. А это делает представление о ЧПТ несколько искусственным.
Другие языки: С, С++, Java, которые оперируют с веществеными числами, в поле тегов не вместились.
Потому что арифметика с плавающей точкой вообще не имеет отношения к языкам.
По первой ссылке language-specific вопрос, который вы в своей статье не рассматриваете, по двум другим — разжёвывание стандарта IEEE 754, просто в тематических сообществах.
Вы упоминаете про бесконечные представления десятичных чисел, сколько гарантированно правильных чисел при 8 разрядной мантисе у 1/5 (0.2)?
n≤⌊0.3*8⌋=2. Преобразуем ваше число в 8-разрядное двоичное: 0.2=0.210 ≈ 0.0011001101≈ 0.2001953125≈0.20. Итого, 2 верные десятичные цифры в 8-разрядном двоичном представлении десятичного числа.
Хотя, наверное я гоню, n=2 это 2 разряда, ну будем считать, что всё работает, но честно говоря мне кажется что может быть ситуация, когда будет не больше, а меньше и тогда получим девятки и минус самый старший разряд.
Не совсем понял.
Максимальное десятичное число с n=2 это 0.99. В 8-ми разрядной мантиссе максимальное число равно 11111111*2^-8=255*2^-8= 0,99609375. В нем 2 верных числа. Числа, которые меньше 0.99 могут быть гарантированно представлены в данной мантиссе.
Я говорю про границу перехода в разряде.
0.09+0.01=0.10 погрешность в сотых, изменяет десятичный разряд.
Более того, сколь угодно малая погрешность может изменить ВСЕ разряды
0.19999999999999999999999999999999999999999 + маленькая погрешность и 0.20000000000000000…
Либо в меньшую сторону:
0.2000000000000000000000000000000000000000 — маленькая погрешность и 0.1999999999999999…
Погрешность же, может может вноситься не операциями, а просто невозможностью представить в виде конечного числа, конечное десятичное. Что непонятно?!
0.2 = 0.1(9)
Итого в представлении числа 0.2 в виде 0.19999999999999999999999999999999999999999 все цифры верные.
Цифры у нас 2 и 0, во втором случае 1 и 9. Мы ведь про цифры говорим, а не про предел числа?
Насколько я понимаю про конкретные цифры говорите только вы, в этом и проблема и недопонимание :)
Я не вижу точного определения «верных цифр», но у вас с автором они различаются. У автора это как раз что-то вроде предела.
По большому счёту ни одной верной цифры, в вашем понимании, арифметика с плавающей точкой гарантировать не может.
Цитирую:
= 9007199254740991*2^-53= 0,99999999999999988897769753748435. Жирным шрифтом помечены верные цифры, соответствующие значащим десятичным цифрам максимального пятнадцатизначного дробного десятичного числа.
Здесь автор не говорит про конкретные цифры?

В моём понимании именно так и есть, вы попали в точку.
Этот пример, приведенный в статье, является иллюстрацией правомерности представления чисел с плавающей точкой в виде целочисленной мантиссы со сдвинутой виртуальной точкой в начало мантиссы. На самом деле, если рассматривать максимальное десятичное 15 разрядное число, то мы получим:
0,999999999999999= 0.999999999999999000799277837359, в котором 15 значащих цифр совпадают с первоначальным числом. Это для формата doable/
Вообще автор утверждает, что если взять дробное десятичное число, перевести в двоичное, усечь мантису, потом обратно, то мы сверяя цифра за цифрой получим сначала полное совпадение, потом начнутся разночтения, и количество совпадений можно посчитать по формуле. Ни о каких точностях чисел тут не идёт речь вообще, речь идёт чисто о количестве «правильных» цифр. Я же утверждаю, что в общем случае это — неверно.
А как вы так перевели? у меня получается вот: 0.00110011=0.19921875 итого 1 разряд точен.
0.2 = 0.00110011001100110011001100110… Округляем до 8 значащих цифр и получаем≈0.0011001101. Вы округлили число до 8 знака после точки. Это случай без нормализации.
В выкладках вы упомнинаете о округлении, в качестве негативного фактора — уменьшается точность.

Округление двоичных чисел приводит к уменьшению учитываемых верных цифр в округленном числе и к изменению неверных цифр в его десятичном эквиваленте


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

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

Каким боком вообще тут округление? Не говоря уже вот про такую дичь:
0.2=0.210

Каким боком вообще тут округление? Не говоря уже вот про такую дичь:
0.2=0.210

Это чисто техническая ошибка. Здесь 10, это система счисления.
Что касается округления, то при разложении несоизмеримого десятичного числа в двоичное, в компиляторе обычно происходит округление до последней младшей цифры, которая помещается в машинную мантиссу.
Да не важно, на самом деле округление, можно так подобрать мантису, что оно не будет оказывать влияния, но мой пример останется тем же. Ответьте на письма в самом низу, которые вы игнорируете.
Я не понял какие значащие 8 чисел вы берёте, потому что у вас 10 бит после точки, ну пусть учитывается и то что перед точкой, тогда 7 должно быть после точки.
Ну пусть даже я взял мало разрядов (тут не 8, а 12): 0.001100110011 = 0.19995117
Я вас не арифметике учу, а спрашиваю про простую суть, как вы гарантируете разряды для таких случаев, ведь точность чисел может быть в плюс, а может и в минус, и если мы перешагиваем границу, то идут лесом все старшие рязряды. На мой взгляд, можно хоть как-то гарантировать точность в смысле отклонения значения, но «точные разряды» это совершенно из другой оперы.
Например 0.999 999 999 9 + небольшая неточность в 0.000 000 000 1 и «точные разряды» и «верные цифры» посыпались.
Я не понял какие значащие 8 чисел вы берёте

Хорошо, хоть вы и пишете:
Это случай без нормализации.

10 бит у вас может получиться только ПОСЛЕ нормализации:
0.0011001100 10бит
0.11001100 <-сдвинули получилось 8 бит + степень
Вот, конкретно только что влепленный минус в вышестоящее сообщение.

Пусть будет «ваша» мантиса, в этом примере 10 бит, что не правильно в вычислениях?
0.001100110011 = 0.19995117

10 бит у вас может получиться только ПОСЛЕ нормализации:
0.0011001100 10бит

Да, после нормализации получается 8 бит мантиссы. Больше не поместится в 8 разрядную машинную мантиссу.
0.11001100 <-сдвинули получилось 8 бит + степень
Вот, конкретно только что влепленный минус в вышестоящее сообщение.

Влепленный минус в чем? В том, что при нормализации надо корректировать порядок характеристики? Ну, так и да.
что не правильно в вычислениях?
0.001100110011 = 0.19995117

В этих вычислениях все правильно. Только количество разрядов машинной мантиссы в вашем примере не 8, а 10. Более того, чем больше разрядов двоичной мантиссы вы будете учитывать, тем более точно будет представляться десятичный эквивалент этого числа.
Если всё правильно тогда сколько правильных цифр для 0.2, при 10битной мантисе и результате 0.19995117?
А при 9 разрядном представлении будет 0.00110011001 или в десятичной системе 0.19970703125
Итого сколько верных десятичных цифр?
Или я неправильно округлил двоичное число?
Тогда возьмём 10 разрядное представление :) Тут должно быть 3 верные десятичные цифры.
При преобразовании туда сюда получим что-то типа 0.199951171875
Сколько тут верных?
Округлим до трех десятичных цифр и получим 0.199951171875≈0.200. Здесь три верные цифры
Дело в том, что усекать или округлять, в принципе, не имеет значения, мы же рассматриваем общий случай, а значит, какие бы мы параметры не подобрали, это будет всего лишь одиним из вероятных вариантов. Например (я буду в своих битах считать, а не после нормализации, как автор):
0.001100110011 = 0.19995117 тут 12 бит после запятой, сделаем меньше:
0.0011001100 = 0.20019531 тут 10 бит
0.00110011 = 0.19921875 тут 8 бит
при 8 и 12 битах округление совпадает с отсечением, потому что дальше 2 нуля, при 9 битах тоже, а вот при 10 битах округление даст какой-то результат. Таким образом можно рассматривать 8 и 12 бит и вопросы будут все те же самые и можно не заострять внимание на округление двоичных чисел.

И да, я думаю что вы неправильно округлили: 0.00110011001(1), по идее должно округляться до 0.00110011010()

Когда десятичное число конвертируется в двоичный код, в основном мы получаем двоичное число, в котором количество значащих цифр превышает разрядную сетку машинной мантиссы. Мы вынуждены округлять такое число. В результате округления мы получаем приближенное двоичное число, в котором цифры, не вошедшие в разрядную сетку машинной мантиссы, усекаются. Десятичное чило, которое можно было представить с любой заданной точностью в двоичном виде, в результате округления его двоичного эквивалента, меняет свое значение. По сравнению с первоначальным числом мы получаем в результате преобразований десятичное число, которое точно представляет округленное двоичное число. Но оно содержит значительно больше десятичных цифр, чем первоначальное десятичное число. Чтобы не рассматривать вновь появившиеся цифры, новое десятичное число округляют. Это новое, уже третье значение десятичного числа будет приближенным числом, по отношению ко второму.
Поэтому к такому числу применим аппарат приближенных вычислений. Согласно теории приближенных вычислений, приближенное (в широком смысле) число содержит как верные, так и неверные цифры. Подчеркну, что понятия верных и неверных цифр имеет смысл только в приближенных числах. Поэтому 0.001100110011 = 0.19995117≈0.2, где 2 — верная цифра.
Чтобы не рассматривать вновь появившиеся цифры, новое десятичное число округляют. Это новое, уже третье значение десятичного числа будет приближенным числом

Я вижу вы на своей волне, больше мне сказать, в общем-то — нечего, поскольку мои аргументы не опровергались. Можете считать 0.199 (если это была продукция от 0.2) за 0.2, а 0.199 (как изначальное значение) за 0.19 любым магическим способом, я «умываю руки».
Можете считать 0.199 (если это была продукция от 0.2) за 0.2

В качестве ликбеза. А за какое число надо считать 0.199, если оно является продуктом числа 0.2?
а 0.199 (как изначальное значение) за 0.19 любым магическим способом,

Это в каких моих рассуждениях вы такое утверждение нашли?
Значащие цифры в учении о приближенных вычислениях это цифры, кроме нуля, а также и ноль в том случае, если он стоит между другими значащими цифрами. [1]
Точность вычисления в вычислительной математике определяется количеством цифр результата, заслуживающих доверия, а не числом десятичных знаков после запятой (см. Березин И.С., Жидков Н.П. Методы вычислений. –М., 1966. –Т. 1. – 632 с.)
Здесь n≤⌊0.39=2⌋. Округляем до 2 десятичных знаков и получаем 0.19970703125≈ 0.20 Здесь гарантированно два верных знака.
Я Вам писал уже в комментариях к предыдущей статье, что, выдумывая какое-то своё учение о верных цифрах вместо хорошо известного и великолепно исследованного понятия погрешности, Вы сами себя запутываете.
Вы мне льстите. К моему сожалению:), учение о верных цифрах и погрешностях в учебниках о приближенных вычислениях рассматриваются в одном разделе. Погрешности являются следствием наличия неверных цифр.
А поскольку числа с плавающей точкой в основном приближенные, то к ним в полной мере применим и аппарат прближенных вычислений.
А статью я написал главным образом потому, что ни в русскоязычной ни в англоязычной литературе не отражена четкая связь между точностью (погрешностью) представления десятичны дробных чисел с размерностью разрядной сетки машинной мантиссы. Даже в таких авторитетных источниках как 1, 2 нет ответа на этот вопрос.
Погрешность – это фундаментальная характеристика любой измеряемой величины, и только одна из её компонентов связана с записью числа в виде цифр.

Источники [1] и [2] описывают двоичное представление вещественных чисел и вообще не касаются чрезмерно любимой Вами десятичной системы.

Если уж Вас занимает вся эта тема, то Вы начните с того, что десятичным числам, непредставимым в двоичной системе с выбранной для расчётов точностью, практически неоткуда появиться в жизни современного человека, так как первоисточником почти всех прецизионных измерений являются двоичные датчики. Можно, если угодно, смотреть на такие числа, как на некий артефакт, позволяющий нам руками записывать на бумаге значения, несуществующие в окружающем нас цифровом двоичном мире (например, упомянутое Вами число 0.2).

Когда вы записали “жульническое” число 0.2, то в действительности это значит только то, что вы заведомо ограничились погрешностью представления 0.05 (половина цены младшего разряда), и рассуждать о более младших разрядах не имеет смысла.
Погрешность – это фундаментальная характеристика любой измеряемой величины, и только одна из её компонентов связана с записью числа в виде цифр.

Написано хлестко, только смысл фразы не ясен. С «фундаментальной характеристикой измеряемой величины» не спорю. А вот про компоненту не понятно. Это относится к фундаментальной характеристике или к измеряемой величине? И как можно число записать без цифр или других символов, однозначно их заменяющих?
Источники [1] и [2] описывают двоичное представление вещественных чисел.

А вещественные числа в какой системе первоначально представляются?
и вообще не касаются чрезмерно любимой Вами десятичной системы

Тут не только меня надо в этом винить. Физики и математики свои уравнения почему-то привыкли решать в десятичной системе счисления. Бухгалтера зарплату тоже считают почему-то в десятичной системе.
десятичным числам, непредставимым в двоичной системе с выбранной для расчётов точностью, практически неоткуда появиться в жизни современного человека, так как первоисточником почти всех прецизионных измерений являются двоичные датчики.
Мне трудно представить, что человечество оперирует исключительно данными двоичных датчиков. Видимо не дотягивает до современного человека.
Можно, если угодно, смотреть на такие числа, как на некий артефакт, позволяющий нам руками записывать на бумаге значения, несуществующие в окружающем нас цифровом двоичном мире (например, упомянутое Вами число 0.2)

Отсюда следует, что число 0.2, все таки существует, а вот его значения в окружающем мире не существует. Вернее существует, но только, не в нашем мире, а в цифровом.

Когда вы записали “жульническое” число 0.2, то в действительности это значит только то, что вы заведомо ограничились погрешностью представления 0.05 (половина цены младшего разряда), и рассуждать о более младших разрядах не имеет смысла.

Чем же число 0.2 вам так насолило, что вы его называете «жульническим»? Не потому ли, что оно никак не вписывается в ваш двоичный мир?
Когда я записал число 0.2, предполагая, что это такая часть от 10 человек, равная 2 человекам, то имел ввиду целых человеков. Т.к. трудно себе представить ошибку в 0.05 человека.

Написано хлестко, только смысл фразы не ясен. С «фундаментальной характеристикой измеряемой величины» не спорю. А вот про компоненту не понятно. Это относится к фундаментальной характеристике или к измеряемой величине? И как можно число записать без цифр или других символов, однозначно их заменяющих?

Начнём с того, что значение можно представить, не записывая число. Например, аналоговым физическим параметром.

Допустим, мы хотим измерить температуру на улице спиртовым термометром. Тогда высота столбика спирта будет кодировать температуру в нецифровой форме, но уже с определённой инструментальной и методической погрешностью. Дальше, если мы будем смотреть на этот термометр глазами и записывать его показания на бумаге в десятичной системе, то прибавится компонент инструментальной погрешности, связанный с визуальным представлением величины на шкале (половина цены деления) и погрешность цифрового представления, равная половине младшего десятичного разряда. Если же мы к этому термометру приделаем датчик для автоматического ввода его значения в компьютер, то прибавится инструментальная погрешность датчика и погрешность цифрового представления, равная половине младшего двоичного разряда.

А вещественные числа в какой системе первоначально представляются?

В наше время, обычно в двоичной.

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

Обычно решают на компьютере в двоичной системе.

Бухгалтера зарплату тоже считают почему-то в десятичной системе.

А эти работают исключительно с целыми числами (или с фиксированной точкой, что то же самое).

Чем же число 0.2 вам так насолило, что вы его называете «жульническим»? Не потому ли, что оно никак не вписывается в ваш двоичный мир?

Именно поэтому. А следовательно, не может легально появиться в порядочном обществе :)

Когда я записал число 0.2, предполагая, что это такая часть от 10 человек, равная 2 человекам, то имел ввиду целых человеков. Т.к. трудно себе представить ошибку в 0.05 человека.

Это арифметика целых чисел.
Начнём с того, что значение можно представить, не записывая число. Например, аналоговым физическим параметром.
Представить себе можно, но передать кому-то это представление возможно только вместе с термометром. А уж в компьютер впихнуть ну никак не получится.
Если же мы к этому термометру приделаем датчик для автоматического ввода его значения в компьютер, то прибавится инструментальная погрешность датчика и погрешность цифрового представления, равная половине младшего двоичного разряда.
Погрешность цифрового представления здесь возникла относительно чего? Относительно аналогового физического параметра, который мы визуально наблюдаем или относительно некоего десятичного числа, которое мы хотели бы представить без погрешностей, ибо эта погрешность — бесплатный бонус, который может испортить нам жизнь.
Когда я записал число 0.2, предполагая, что это такая часть от 10 человек, равная 2 человекам, то имел ввиду целых человеков. Т.к. трудно себе представить ошибку в 0.05 человека.

Это арифметика целых чисел.
Вся арифметика вытекает из взаимоотношений целых чисел. Хорошее целое число 3 и хорошее целое число 7 при делении дают отвратительное число 3/7, которым недовольны, как в приличном обществе так и в не очень:).
Компьютеру совершенно все равно, с какой биографией ему подсовывают число. Он его врспринимает для себя точным, а уж потом портит, в силу своей природы.
Представить себе можно, но передать кому-то это представление возможно только вместе с термометром.

Почему нельзя? Можно. Например, уровнем напряжения в проводе.

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

Погрешность цифрового представления здесь возникла относительно чего?

Относительно измеренного датчиком параметра.

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

Без погрешностей ничего не бывает.

Вся арифметика вытекает из взаимоотношений целых чисел. Хорошее целое число 3 и хорошее целое число 7 при делении дают отвратительное число 3/7, которым недовольны, как в приличном обществе так и в не очень:).

Хорошее целое число 3 и хорошее целое число 7 при делении дают хорошее целое число 0.

Компьютеру совершенно все равно, с какой биографией ему подсовывают число. Он его врспринимает для себя точным, а уж потом портит, в силу своей природы.

Это так, но мы-то умнее компьютера и знаем биографию.
Почему нельзя? Можно. Например, уровнем напряжения в проводе.

Какие бы вы физические преобразования ни делали, компьютеру вы должны предъявить число, которое записывается цифрами 0...9 или 0,1 или любыми другими. Все прочее он не понимает.
Без погрешностей ничего не бывает.
Бывает, например, для некоторых операций с целыми числами. А когда погрешности неизбежны, их можно уменьшить или увеличить, выбирая те или иные параметры представления чисел в компьютере.
Хорошее целое число 3 и хорошее целое число 7 при делении дают хорошее целое число 0.
Скажите это продавцу, который рассыпает 3 кг. сахара по 7 пакетов. Он будет счастлив.
У продавца погрешность не менее 10 граммов. Он делит 3.00 на 7 и получает 0.42.

А компьютер 9 не понимает, он понимает 0 и 1.
Добавлю, что в примере с термометром наибольшим компонентом погрешности, скорее всего, окажется методическая, связанная с тем, что висит он на стене дома и нагревается от него, и в этом свете все рассуждения, связанные с погрешностью перевода из десятичной системы в двоичную, окажутся ни к чему.

Как правило, в реальности определяющее значение имеет либо методическая или инструментальная погрешности, не связанные с числовым представлением величины, либо погрешность вычислений, имеющая чисто компьютерную, двоичную природу.
Как правило, в реальности определяющее значение имеет либо методическая или инструментальная погрешности, не связанные с числовым представлением величины, либо погрешность вычислений, имеющая чисто компьютерную, двоичную природу.
Вот на тех, кому важна погрешность вычислений, имеющая чисто компьютерную, двоичную природу и расчитана моя статья.
Есть форматы decimal floating point, например. Они стандартизированы, и их можно использовать. Вы рассматривали этот вариант?
Существует много способов получить точные результаты арифметических вычислений, но при решении конкретных задач приходится учитывать и другие факторы, такие, как скорость обработки, сложность алгоритма. Арифметика с плавющей точкой, реализованная в двоичном виде, сегодня самая простая и быстрая в реализации. Поэтому, не смотря на ее большие вычислительные погрешности, интерес к ней не уменьшается.
Sign up to leave a comment.

Articles