Как стать автором
Обновить
0
0
Спиридонов Юрий Маркович @Innotor

Изобретатель

Отправить сообщение
«можно через двоичный, умноженный на коэффициент.»
Вы эту фразу имеете ввиду?
Это высказывание моего оппонента. Здесь имелось ввиду, наверное, десятичный логарифм двойки. По крайней мере, именно в этом смысле я воспринял его вольное высказывание. Что же касается равенства lbX=logX, то однозначно это неверно.
Я написал алгоритм, который описан в этом комментарии

В этом коментарии нет алгоритма округления десятичного числа представленного двоичным кодом.
(«умножение числа и последующее после округления деление») и встречается много где в интернете (1, 2, 3, 4).

Вы правы, алгоритм «умножение числа и последующее после округления деление» много раз встречается в интернете. Только в ваших ссылках я насчитал более 20 алгоритмов округления. Но, «стандартного» не обнаружил.
что вас не устраивает в существующих средствах?

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

Вы мне дали ссылку на поисковую страничку google и предлагаете просмотреть все ссылки, чтобы убедиться, что «Через десятичный логарифм в интернете встречается чаще». Но почему-то на страницах, которые вы указали в предыдущих 3-х ссылках я не встретил ни одного алгоритма использующего этот способ.
Что касается «можно через двоичный, умноженный на коэффициент.» Но, что-то я тоже не нашел ни одного алгоритма, кроме моего и чудесным образом «вашего», где бы использовался такой способ определения коэффициента.
Я написал алгоритм… Если это то же самое, что написали вы, тогда непонятно, почему вы говорите, что что-то где-то неправильно округляется.

Вы написали программу по моему алгоритму. Но дьявол кроется в деталях.
Замечательно! Вы взяли мой алгоритм, один к одному его переписали и выдали его за свой. Может быть вы мне тогда объясните, зачем вы применили эту функцию -(int)floor(e * 0.301)? И дадите ссылку на стандартный алгоритм, где она используется. Буду очень благодарен.
На какую степень десятки надо умножить двоичное число, приведенное мною?
В результате некоторых вычислений вы получили какое-то double-число: 1.0011… 00011*2^123 (любое). Вам из него надо получить двоичное число, равное ближайшему к правильно округленному до 7 десятичных знаков десятичному числу.
Все, больше вам ничего не известно. Как это сделать без конвертации этого числа в десятичный код стандартной программой округления?
Еще раз повторю. Речь идет не об округлении десятичных чисел, выведенных на консоль. А о десятичном округлении двоичных чисел doable, десятичный эквивалент которых вам неизвестен пока вы не преобразуете doable в десятичное число с помощью printf.
Дело же в остальном алгоритме.

Да нет, квинтэссенция моего алгоритма именно в том и состоит, что по двоичному doable определяется десятичное значение экспоненты. Когда это значение определено, дальше преобразования идут по стандартному алгоритму десятичной арифметики. Когда вы применяете функцию atof, вы в ней задаете десятичное значение экспоненты, вводя ее при печатании вручную. Но в doable может храниться произвольная двоичная экспонента для двоичного числа, десятичное значение которого вам не известно…
Другая проблема возникает при сохранении чисел из более широкого формата в более узкий. Например, double в float, расширенный doable в простой double. Последний случай сэмулировать сложно, поэтому я написал тестовую программу округления более широкого формата до более низкого с использованием double. Другие случаи просто масштабируются.
Так вот, проблема в том, что до одного и того же числа можно округлить разные числа. Например, два double — числа 5.50624245984287807511338305951E-17и 5.50624155984287824709987743381E-17, округленные до 14 и менее значащих цифр будут иметь одно и то же значение. (Я специально увеличил |значение| экспоненты). Так, округленное до 7 значащих цифр наше число, это 5.506242. Опять же, в десятичной арифметике, ни каких проблем здесь не возникает. Берем и округляем, если вычислили десятичную экспоненту. Но в двоичном представлении все гораздо сложнее.
Возьмем число 5.50624245984287807511338305951E-17. Его двоичное представление будет таким 1.1111101111011100011110010110010011010000110111101111*2^-55.
Мы знаем, что в мантиссу float можно записать 24 бита. Округляем наше double-число до 24 значащих цифр с погрешностью <=0.5ulp. Получим 1.11111011110111000111101*2^-55= 5,5062425601282510780228041102902e-17≈5,506243. В результате правильного округления двоичного числа double с погрешностью <0.5 ulp мы получили округление его десятичного эквивалента c погрешностью>1ulp. Ближайшим же к правильно округленному десятичному числу будет float-число 5.50624189838376103560066421316E-17.
Спасибо за толковый ответ.
Округление десятичного числа с плавающей запятой — тривиальная задача, если известна его экспонента и что число — нормализованное. Проблема заключается в нахождении значения десятичной экспоненты. Функция frexp в моем алгоритме просто считывает значение двоичной экспоненты e в числе double. Не знаю, насколько это легко выполнить программно, но аппаратно это осуществляется за 1 такт. Для определения десятичной экспоненты осталось вычислить floor(e*double(value*0.301)). Думаю, это реализовать проще, чем вычислить log 10(value). А что вы думаете?

Спасибо. Только, поскольку я в программировании чайник, не могли бы вы эту программу расписать алгоритмически или на языке математики?
Производительность достигается распараллеливанием вычислений, а не перемалыванием чисел-монстров. Но, на эту тему я дальше спорить не буду. К моему алгоритму это отношения не имеет.
И он, что характерно, с этим справляется.

Да вот, оказывается, не очень. Зачем-то заменили 32-разрядные компьютеры на 64-разрядные, а теперь и на 128. А еще работают над 256 разрядными? Вам ни кажется это странным? Вы представляете себе это десятичное число с плавающей запятой? А все ради нее, ради точности стараются.
Вставляйте округление в место, где посчитаете нужным, продемонстрируйте результат.

Своими ручками пожалуйста. Вставьте где нужно мое округление и покажите, что оно не работает. Вся информация для этого в статье и в коментах. Если будут вопросы, обращайтесь.
Для вас математика — учебник Брадиса. Для меня -Modern Computer Arithmetic Richard P. Brent and Paul Zimmermann
На том простом основании, что все компьютеры работают по теории, изложенной в этом учебнике, а не в учебнике Брадиса. Поэтому мы с вами на разных языках разговариваем.
Вы плохо усвоили, то, что написано мною выше. Т.к. не читали. П вотому что не написали ни одного возражения, кроме набора тривиальных фраз.
Проверить это утверждение очень легко. Сосчитайте с использованием округления то, что легко проверяется аналитически (sin(pi) через ряд), или сравнением (дважды обращенная матрица равна сама себе).

Вы жаждете, чтобы я сам себя «зарезал», а вы постояли в сторонке, а потом сказали — Ну, вот, что я говорил. Нет, батенька, потрудитесь сами. Получите результаты, правильно их интерпретируйте, а затем мы с вами их обсудим. ОК?
Как-то вы неясно излагаете свою мысль. Что? Вопросы точности разработаны так давно, что уже не актуальны? Или вас возмущает факт «рождения хренов с горы»? Что мы обсуждаем то? И где здесь математика?
Да, вы правы. В Багдаде не спокойно:).
У.Кэхэна читал, Д.Голдберга читал, Харрисона читал, Циммермана читал. Брадиса? Кажется в школе проходили. А в чем дело?
Если вы ознакомились со статьей «Что такое точность?», то в рамках рассматриваемой там терминологии можно сказать. Если длинна мантиссы двоичного нормализованного числа не меняется, то любые арифметические преобразования в парадигме IEEE754 не приводят к изменению точности p (precision) представления числа. Если она меняется, например для субнормальных чисел, то точность (precision) уменьшается.
Для десятичных чисел в двоичном коде другая ситуация. Изменение длинны двоичной мантиссы может приводить к потере точности десятичного числа, может повышать точность, а может и не менять ее. Повышение точности в смысле accuracy, т.е. близости к теоретическому результату мы и обсуждали в комментах выше.
Ну и пример того, когда десятичная точность не меняется при сокращении длинны мантиссы. Если число точное (exact) и представимо в мантиссе с p разрядами, то оно представимо и точно (exact) в мантиссе с p+n разрядами. Отсюда, усечение n разрядов двоичной мантиссы приводит к уменьшению precision, но exact и accuracy не меняются. Так, число 0.125 можно представлять 64-мя,24-мя или 3-мя значащими цифрами, его значение не изменится.

Информация

В рейтинге
Не участвует
Откуда
Минск, Минская обл., Беларусь
Зарегистрирован
Активность