Коррекция значения результата ошибки с плавающей запятой?
Получаю по вебсокету (данные не я стряпаю) иногда вот таких например жертв фичи с плавающей запятой
0.9192899999999999
3.234000000000001
Чтобы не задавать вектор и разрядность округления для каждого значения, можете подсказать общий метод округления с минимальными накладными расходами?
Очевидно, значения должны выйти
0.91929
3.234
питоновский float. хотя можно и string, всё равно дальше на вебсокет пулять
UPD:
Если задача труднореализуема или попросту непонятна ввиду косноязычного изложения, прошу помочь с регулярным выражением для отсечки справа всех девяток (или нулей) вместе со совсем что правее, если их (девяток или нулей) больше пяти подряд.
Спасибо.
shurshur, нет, не вариант. Я же сразу указал что "полезных" цифр после запятой может быть разное количество, и их все нужно сохранить.
А куча девяток и нулей поле них это отрыжка вычисления (хранения) в двоичной системе, нужно округлять обратно или отсекать.
Лишние цифры тоже не нужны
GreenX5, решение, предложенное shurshur, - рабочее для приведенных в вопросе примеров.
Попробовал бы для начала хоть строку кода в питоне написать и запустить, прежде чем голословно утверждать, что не вариант.
soremix, тогда ставишь округление до 8 знаков и все продолжает работать. Настолько невероятно, что даже не верится. Но легко проверяется. А вот угадывать, какие там могут быть случаи - дело неблагодарное.
GreenX5, вопрос исправлен, но мне не стало очевидно, по какому признаку ты решаешь, какая часть числа значимая, а какая мусорная. Почему вдруг последовательность девяток или нулей стала «очевидно» незначимой?
GreenX5, потому что это не логично, не так ли? Более очевидны формальные требования, которые ты не сформулировал. Также как и не описал граничные случаи.
Roman Kitaev, не, не так. Наличие пяти нулей или девяток в конце дробной части числа плюс любое число последнее и минимальные машинные ресурсы на проверку и коррекцию - вполне конкретные формальные требования.
GreenX5, это что-то на грани реальности или уже за ней. Речь о числах с плавающей запятой, их арифметике и точности представления. Попробуй держаться в разумных пределах. После запятой в питоне будет максимум 15 или 16 цифр. Пятью из них вполне можно пожертвовать во многих реальных задачах. Ну или тремя. Если нельзя, то изначально питоновский тип float не годится для использования в этом случае.
kamenyuga, ок, ну тогда давай попробуем решать задачу в рамках вопроса? По куче нолей или девяток в конце числа предполагаем что это жертва трудностей перевода и возвращаем ему предполагаемое правильное значение.
Напоминаю условие - мы имеем дело с данными любой разрядности в рамках float python.
Значащими являются цифры в мантиссе. При этом возможны всякие казусы, например: 1+(1e-17)=1 - потеря точности, так как в мантиссе не может быть 18 значащих цифр, хотя 1 и 1e-17 не теряют точности по отдельности - там всего одна значащая цифра.
shurshur, да, спасибо за подтягивание теории, я ни в коем случае не вступаю в спор с Вами по этим вопросам. Просто рано или поздно хочется положить в закрома какое-то рабочее решение для исправления битых конвертациями чисел. Это проблема всех машинных языков, помню еще в LUA нужно было решать когда писал биржевых ботов лет 15 назад, там котировки требовали строго определенной не побитой разрядности. И разрядность у многих фин. инструментов была разная.
Конечно, заведомо определяя разрядность каждой переменной как условие результата, можно её проверять и даже передавать при обмене второй переменной, как например раздает Яху финанс в своих JSON. И рамках моей задачи сейчас мне действительно пока оказалось достаточно round 5, даже без проверки индивидуальных разрядностей. Но это "пока". Даже в мире финансов есть разрядности поболее 5 знаков после запятой. А в области bigdata это вообще дает катастрофические суммарные итоговые погрешности, и это давно известная проблема.
Строковое представление я дал чтобы чья-н. среда разработки не округлила для вывода в интерфейсе. Не так уж это странно. ) Вот выше kamenyuga утверждал что "После запятой в питоне будет максимум 15 или 16 цифр", я, чтобы не начать торговаться с ним как на базаре, дал число с 17-ю, причем не импортированное, это родил питон в результатом арифм. операции.
Сейчас проверю ваше round(x, sys.float_info.dig)
Спасибо.
Если у тебя непреодолимые предубеждения против этого метода решения задачи, что ты до сих пор ищешь условия, где он не работает, - то не продолжай, остановись, сделай глубокий вдох. А потом используй любой велосипед, который сможешь изобрести. Утри всем нос. А я в силу своих ограниченных способностей просто не могу постигнуть нестерпимую точность яху финансовой бигдаты.
GreenX5, а вот как понять, сколько цифр в записи 0.919289999999999 являются значащими, а сколько - ошибкой округлений?
Так-то не очень сложно написать алгоритм, который найдёт на конце все девятки и затем передаст в round(x, текстовая_длина_числа-число_девяток) (не совсем так, так как в текстовую длину входит знак и десятичная точка, но принцип должен быть понятен), но такой алгоритм и 0.9 превратит в 1, а ведь это вряд ли задумывалось.
В итоге всё упирается в то, какая конкретно точность ожидается от чисел. Сколько в них значимых цифр? Вот эту величину и надо передать вторым аргументом round. А 0.919289999999999 с 16 значащими цифрами вполне легально не округляется.
shurshur,
Я же вроде понятно дал формальные требования для пути к решению задачи. Первый пост, после UPD:
Например путем поиска регулярными выражениями пяти девяток или нулей. Да, конвертация в строку и обратно накладно, не лучшее решение, но хоть какое -то.
kamenyuga, ну никогда не поздно и не постыдно раздвигать границы своих "ограниченных возможностей", за тем мы и на Хабре, правда? )
Не расслабляйтесь, вот вам 324 знака после запятой в float