Округлите число с плавающей запятой до n цифр, игнорируя ведущие нули и сохраняя их - PullRequest
1 голос
/ 26 июня 2019

с плавающей точкой = 11.0000123456789

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

У меня есть следующее, оно короткое и приятное, но немного похоже на работу.

import decimal

decimal.getcontext().prec = 4
significand, base = str(11.0000123456789).split('.')
fp = significand + str(decimal.Decimal('.' + base) + 0)[1:]  # I need to add 0 here for it to work
print(fp)

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

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

Ответы [ 2 ]

2 голосов
/ 26 июня 2019

Я думаю, что это самый питонический способ решения вашей проблемы.Попробуйте,

>>> import re
>>>
>>> float_val = 11.0000123456789
>>> keep_places = 4
>>>
>>> regEX = f'[0-9]+\.[0]+{"[0-9]" * keep_places}'
>>> expected_val = re.search(regEX, str(float_val)).group()
>>>
>>> print(expected_val)
'11.00001234'

Самый простой способ - создать Операции с регулярными выражениями , и именно так я использую его для решения вашего вопроса.Давайте разберем его на 4 части.

  1. [0-9]+
  2. \.
  3. [0]+
  4. [0-9] * keep_places

(1).[0-9] означает выбор только одной цифры от 0 до 9. Нам нужно несколько цифр перед десятичной точкой.Вот почему мы добавляем [0-9]+.Если перед десятичной запятой у вас нет целых чисел, то добавьте * вместо +, чтобы проверить ноль или более вхождений.Если вы используете +, значит, вы должны иметь одно или несколько значений.

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

(3).[0]+, это будет соответствовать всем нулям в нашей строке.

(4).[0-9] * keep_places, это просто умножение строк.Для этого вопроса keep_places равно 4, что означает, что мы получаем такой вид вывода [0-9][0-9][0-9][0-9].Но в Операциях регулярного выражения он выбирает только четыре цифры, каждая из которых находится в диапазоне от 0 до 9. Еще одна вещь, для этого вопроса не имеет значения, используете ли вы [0-9] или [1-9].Поскольку мы уже записываем нули, он начинает находить другие целые числа из 1.

Если вы напечатаете regEX, все вместе вы увидите [0-9]+\.[0]+[0-9][0-9][0-9][0-9] строку типа.Он соответствует только типу <any_number><dot><all_zeros_before_the__non_zero_integer><4_digit_after_last_zero>.Вы можете проверить это выражение онлайн .

1 голос
/ 26 июня 2019

Редактировать: для неизвестного числа 0 я не вижу лучшей альтернативы, чем

import re
some_float = 11.00001203456789
how_many_to_keep = 4
regex = r"0[1-9]"
float_part = str(some_float).split(".")[1]
float_limiter = re.search(regex,float_part).start() if float_part.startswith("0") else -1
print(f'{some_float:2.{float_limiter+1+how_many_to_keep}f}')

, которая оценивает число 0 в реальном времени, используя выражение float_limiter+1+how_many_to_keep, и использует в качествепараметр формата.это стало немного некрасиво, но теперь возвращает правильный ответ на все случаи.Выходное значение равно

11.00001235

...