Python float () ограничение по научной нотации - PullRequest
0 голосов
/ 29 апреля 2018
  • питон 3.6.5
  • numpy 1.14.3
  • scipy 1.0.1
  • Цербер 1.2

Я пытаюсь преобразовать строку '6.1e-7' в число с плавающей запятой 0.00000061, чтобы сохранить его в поле mongoDb.

Моя проблема здесь в том, что float ('6.1e-7') не работает (он будет работать для float ('6.1e-4'), но не для float ('6.1e-5') и более) .

Python float

Кажется, я не могу найти никакой информации о том, почему это произошло, по ограничениям по числам , и во всех найденных мной примерах показано преобразование на e-3, никогда до этого.

Numpy

Я установил Numpy, чтобы попробовать float96 () / float128 () ... float96 () не существует и float128 () возвращает float '6.09999999999999983e-07'

Формат

Я попробовал 'format (6.1E-07,' .8f ')', который работает, так как он возвращает строку «0.00000061», но когда я конвертирую строку в число с плавающей точкой (таким образом, он может пройти проверку cerberus ) он возвращается к «6.1E-7».

Любая помощь по этому вопросу будет принята с благодарностью.

Спасибо

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

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

Во внутреннем формате числа не содержат никакой информации о форматировании, как целые числа и числа с плавающей запятой. Для целого числа 123 нельзя восстановить, было ли оно представлено в виде "123", " 123 " (с тоннами пробелов до и после него), 000000123 или +0123. Для плавающего числа можно использовать 0.1, +0.0001e00003, 1.000000e-1 и множество других форм. Внутренне все они должны приводить к одному и тому же номеру.

(Есть некоторые особенности, когда вы используете IEEE754 «десятичное плавающее число», но я уверен, что это не ваш случай.)

При сохранении в базе данных внутреннее представление перестает иметь большой смысл. Вместо этого специфика базы данных начинает играть роль, и она может быть совершенно другой. Например, SQL предлагает использовать типы столбцов, такие как numeric(10,4), и каждое значение будет преобразовано в десятичный формат, соответствующий типу столбца (обычно сохраняется на диске в виде текстовой строки с десятичной точкой или без нее). В MongoDB вы можете хранить плавающее значение либо в виде числа JSON (IEEE754 double), либо в виде текста. Каждый вариант имеет свою специфику, но если вы выбираете текст, вы несете ответственность за правильное форматирование каждый раз, когда формируете этот текст. Вы хотите увидеть десятичное число с фиксированной точкой с 8 цифрами после точки? Хорошо, никаких проблем: вы просто должны форматировать в соответствии с %.8f при каждой подготовке такого представления.

Проблемы с выбором представления:

  1. Уникальность: никакие разные формы не должны быть доступны для одного и того же значения. В противном случае вы можете, например, сохранить одно и то же содержимое под несколькими ключами, а затем принять старое за последнее.
  2. Осведомленность о заказе: БД должна быть в состоянии обеспечить естественный порядок значений для запросов типа "пара ключ-значение потолка".

Если вы всегда форматируете значения, используя %.8f, вы достигнете уникальности, но не упорядочения. То же самое для %.g, %.e и других текстовых форматов, за исключением специальных (не читаемых человеком), которые созданы для сохранения такого порядка. Если вам нужно упорядочить, просто используйте числа в качестве чисел и не концентрируйтесь на том, как они выглядят в текстовых формах.

(И ваша проблема не связана с numpy.)

0 голосов
/ 29 апреля 2018

'6.1e-7' это строка:

>>> type('6.1e-7')
<class 'str'>

Пока 6.1e-7 - это число с плавающей запятой:

>>> type(6.1e-7)
<class 'float'>

0.00000061 совпадает с 6.1e-7

>>> 0.00000061 == 6.1e-7
True

И, внутри, это число с плавающей точкой представлено 0 и 1. Это просто еще одно представление того же числа с плавающей точкой.

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

>>> '0.00000061' == '6.1e-7'
False

И вы не можете сравнивать строки с числами:

>>> 0.00000061 == '6.1e-7'
False
...