Я хочу, чтобы a был округлен до 13,95.
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
Важно, чтобы валюта не была плавающей. Поплавки неточные. Но суммы в пенни или центах - целые числа. Следовательно, целые числа - это правильный способ представления валюты.
@ DavoudTaghawi-Nejad или более точно ... Десятичный тип
Хм ... Вы пытаетесь представлять валюту? Если это так, вам не следует использовать поплавки для долларов. Вероятно, вы могли бы использовать числа с плавающей запятой для пенни или любой другой наименьшей общей денежной единицы, которую вы пытаетесь смоделировать, но лучше всего использовать десятичное представление, как предложил ХУАГАГУА в своем ответе.
@Basic, это зависит (в основном нет). Использование целых чисел в центах или пенни - это доказательство глупости. Это отраслевой стандарт представления денег. Если вы знаете, что делаете, хорошо разбираетесь в арифметике с плавающей запятой и десятичном классе Python, вы можете использовать decimal. Но это во многом зависит от вашей проблемы. Вам нужны десятичные дроби произвольной точности? Или всего две цифры? Если две цифры: целое. Это убережет вас от неприятностей. Источник Я работал в консалтинговой компании по программному обеспечению для банковского дела.
Я, наверное, приду сюда слишком поздно, но я хотел спросить, решили ли разработчики Python эту проблему? Потому что, когда я округляю (13,949999999999999, 2), я просто получаю 13,95. Я пробовал это в Python 2.7.6, а также в 3.4. Оно работает. Не уверен, что 2.7 вообще было там в 2009 году. Может быть, это вещь Python 2.5?
@bad_keypoints: Да, проблема округления решена с помощью Python 2.7.0+. Подробнее в мой ответ здесь
@ DavoudTaghawi-Nejad суммы пенни или цента являются целыми числами, не по ценам на бензин ...
Они по-прежнему целые, но с более низким базовым значением. Например, 0,5 цента будет 500 номиналом 1/1000 цента.
Он работает для меня на Python 2.7. Должно быть обновлено






Вы сталкиваетесь с старая проблема с числами с плавающей запятой, которые не все числа могут быть представлены точно. Командная строка просто показывает вам полную форму с плавающей запятой из памяти.
С представлением с плавающей запятой ваша округленная версия - это то же самое число. Поскольку компьютеры являются двоичными, они хранят числа с плавающей запятой как целое число, а затем делят его на степень двойки, так что 13,95 будет представлено аналогично 125650429603636838 / (2 ** 53).
Числа с двойной точностью имеют точность 53 бита (16 цифр), а обычные числа с плавающей запятой имеют точность 24 бита (8 цифр). тип с плавающей запятой в Python использует двойную точность для хранения значений.
Например,
>>> 125650429603636838/(2**53)
13.949999999999999
>>> 234042163/(2**24)
13.949999988079071
>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999
Если у вас есть только два десятичных знака (например, для отображения значения валюты), у вас есть несколько лучших вариантов:
Но как насчет того, чтобы число увеличилось с 13,95 до, скажем, 13,90? Тогда мой результат будет 13,9. Я бы хотел, чтобы он показывал ноль.
@Christian Существует фундаментальная разница между сохраненным значением и тем, как вы отображать это значение. Форматирование вывода должно позволить вам добавлять отступы по мере необходимости, а также добавлять разделители запятых и т. д.
Стоит отметить, что "%.2f" % round(a,2) можно вставлять не только в printf, но и в такие вещи, как str()
почему люди всегда предполагают, что валюта округляется с плавающей запятой? иногда просто хочется работать с меньшей точностью.
Следует отметить, что "%.2f" %0.245 будет выводить '0.24', т.е. он округляет только 6 или больше
@ user2426679: Кажется, вы не поняли этого ответа. Попробуйте округлить 0,225 до двух десятичных знаков.
Примечание. В формате 0 позиционный аргумент не нужен в python 2.7 или 3.1, я думал, что это часть формата и получил странные результаты :) ("{: .2f}". Format (a)
@JohnY, почему тогда 0,245 раунда до 0,24, а 0,225 раунда правильно? Хотелось бы 0,245 округлить до 0,25
@radtek: Вы должны понимать, что двоичное значение (типа float) - это всего лишь ближайшая доступная аппроксимация десятичного числа (с которым вы знакомы как человек). Не существует такого (конечно представимого) двоичного значения, как 0,245. Его просто не существует, а математически не могу существует. Двоичное значение, которое ближе всего к 0,245, немного меньше, чем 0,245, поэтому, естественно, оно округляется в меньшую сторону. Точно так же в двоичном формате нет такой вещи, как 0,225, но двоичное значение, которое ближе всего к 0,225, немного больше чем 0,225, поэтому, естественно, оно округляется в большую сторону.
@JohnY Я не просил объяснений, просто решение. Я думаю, что единственное решение - использовать десятичный тип, если только кто-то не может назвать лучший.
@radtek: Вы буквально просили объяснений. Самым простым решением действительно является использование Decimal, и это было одно из решений, представленных в этом ответе. Другой заключался в преобразовании ваших количеств в целые числа и использовании целочисленной арифметики. Оба этих подхода также упоминались в других ответах и комментариях.
Кстати, начиная с Python 3.6 мы можем использовать f-строки: f"Result is {result:.2f}"
как это работает, если я хочу добавить строку вперед, например: print ('blabla floatnumber function (x))
Я не мог правильно понять, почему питон хранит число, а затем делит его на другое число вместо хранения реального значения числа? Почему у нас этого нет в C++, C# или ...? Почему мы не можем сохранить 0,0001_0000_0000_0000 ... для 0,1?
@MahdiAmrollahi: У компьютеров есть биты. Они не могут хранить «реальные числа». Они просто складывают кусочки и интерпретируют их обычным образом. Для целых чисел это довольно просто (многие биты - это число с основанием 2). Но только с 0 и 1 вы не можете сохранить «реальное значение», особенно если реальное значение является иррациональным значением (например, пи). Арифметика IEEE-754 (float в Python, float / double в C / C++ / C#) эффективна и «достаточно близка». Существуют более точные варианты (fractions.Fraction, decimal.Decimal; последний использует формат хранения, аналогичный тому, который вы просите), но они медленнее и больше.
Вы можете изменить формат вывода:
>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95
Он делает именно то, что вы ему сказали, и работает правильно. Узнайте больше о путаница с плавающей запятой и, возможно, попробуйте вместо этого объекты десятичный.
Большинство чисел не могут быть точно представлены в числах с плавающей запятой. Если вы хотите округлить число, потому что это то, что требует ваша математическая формула или алгоритм, тогда вам нужно использовать round. Если вы просто хотите ограничить отображение определенной точностью, даже не используйте round и просто отформатируйте его как эту строку. (Если вы хотите отобразить его с помощью какого-либо альтернативного метода округления, а их много, вам нужно смешать два подхода.)
>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'
И, наконец, что, пожалуй, наиболее важно, если вам нужна математика точный, вам вообще не нужны числа с плавающей запятой. Обычный пример имеет дело с деньгами и хранением «центов» как целого числа.
Учебник Python имеет приложение под названием Арифметика с плавающей запятой: проблемы и ограничения. Прочтите это. Он объясняет, что происходит и почему Python делает все возможное. Есть даже пример, соответствующий вашему. Позвольте мне немного процитировать:
>>> 0.1 0.10000000000000001you may be tempted to use the
round()function to chop it back to the single digit you expect. But that makes no difference:>>> round(0.1, 1) 0.10000000000000001The problem is that the binary floating-point value stored for
“0.1”was already the best possible binary approximation to1/10, so trying to round it again can’t make it better: it was already as good as it gets.Another consequence is that since
0.1is not exactly1/10, summing ten values of0.1may not yield exactly1.0, either:>>> sum = 0.0 >>> for i in range(10): ... sum += 0.1 ... >>> sum 0.99999999999999989
Альтернативой и решением ваших проблем было бы использование модуля decimal.
Появились новые спецификации формата Спецификация строкового формата Мини-язык:
Вы можете сделать то же самое, что и:
"{:.2f}".format(13.949999999999999)
Примечание 1: выше возвращает строку. Чтобы получить float, просто оберните float(...):
float("{:.2f}".format(13.949999999999999))
Обертывание Заметка 2: с float() ничего не меняет:
>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True
Чтобы добавить запятые, вы также можете '{0:,.2f}'.format(1333.949999999), который печатает '1,333.95'.
@ OnurYıldırım: да, но вы можете обернуть это float(); float("{0:.2f}".format(13.9499999))
@JossefHarush, вы можете обернуть его с помощью float (), но вы ничего не получили. Теперь у вас снова есть поплавок с той же неточностью. 13.9499999999999 и 13.95 - это одно и то же число с плавающей запятой.
@NedBatchelder: я согласен, что они равны, но это ограничивает число с плавающей запятой двумя десятичными точками :)
Нет возможности «округлить» число. Форматирование просто для красивой печати. Если вам действительно нужно хранить цифры (например, отслеживать деньги), используйте целые числа.
@NeilChowdhury Верно, я спросил меня то же самое после того, как написал ответ. Предположение вопроса состоит в том, чтобы отобразить число с плавающей запятой с точностью до двух десятичных знаков.
Обратите внимание, что если вы хотите отформатировать более одного числа, вам нужно увеличить целое число перед двоеточием: >>> print ("{0: .2f} - {0: .2f}". Format (.1234, .5678 )) 0,12 - 0,12 >>> print ("{0: .2f} - {1: .2f}". Format (.1234, .5678)) 0,12 - 0,57
Кстати, начиная с Python 3.6 мы можем использовать f-строки: f"Result is {result:.2f}"
Попробуйте следующий код:
>>> a = 0.99334
>>> a = int((a * 100) + 0.5) / 100.0 # Adding 0.5 rounds it up
>>> print a
0.99
Но будьте осторожны, значение a по-прежнему является неточным. Взгляните сюда - repl.it/LJs (нажмите «Запустить сеанс» в верхней части правого раздела).
Если вы придерживаетесь этого подхода, вам следует добавить 0,5 для более точного представления. интервал (а * 100 + 0,5) / 100,0; Другой вариант - использовать math.ceil.
Если участник собирается проголосовать против этого ответа, пожалуйста, предоставьте объяснение, чтобы мы могли понять, что не так в этом подходе. По причине, упомянутой OriolJ, я считаю, что это лучший ответ.
@ShashankSawant: Ну, во-первых, ответ в представленном виде не округляется, а обрезается. Предложение добавить половину в конце будет округлено, но тогда в этом нет никакой пользы, чем просто использовать функцию round в первую очередь. Во-вторых, поскольку это решение все еще использует плавающую точку, исходная проблема OP остается даже для «исправленной» версии этого «решения».
-1, это просто ненужная повторная реализация функции round (которая использовалась в вопросе).
@interjay, который необходим, если round() не работает, как указано в OP.
Это отлично работает в Python 3, вам просто нужно убедиться, что вы включили .0 в знаменатель.
@Pithikos round() работает нормально, и этот код не работает лучше. Проблема в том, что Python использует двоичные числа с плавающей запятой, и наиболее близким к 13.95 является 13.949999999999999. Если вы видите код, который генерирует любое другое число, это потому, что при преобразовании в строку применяется большее округление. См. Математика с плавающей запятой не работает?.
Для Python <3 (например, 2.6 или 2.7) это можно сделать двумя способами.
# Option one
older_method_string = "%.9f" % numvar
# Option two (note ':' before the '.9f')
newer_method_string = "{:.9f}".format(numvar)
Но обратите внимание, что для версий Python выше 3 (например, 3.2 или 3.3) второй вариант - предпочтительный.
Для получения дополнительной информации о втором варианте я предлагаю эту ссылку на форматирование строк из документации Python.
И для получения дополнительной информации о первом варианте этой ссылки будет достаточно, и она содержит информацию о различных флагах.
Ссылка: Преобразуйте число с плавающей запятой до определенной точности, а затем скопируйте в строку
Как вы представляете целое число? Если я использую "{i3}". Format (numvar), я получаю сообщение об ошибке.
Вот что я имею в виду: если numvar=12.456, то "{:.2f}".format(numvar) дает 12.46, но "{:2i}".format(numvar) выдает ошибку, и я ожидаю 12.
Для исправления плавающей запятой в языках с динамическим типом, таких как Python и JavaScript, я использую эту технику.
# For example:
a = 70000
b = 0.14
c = a * b
print C# Prints 980.0000000002
# Try to fix
c = int(c * 10000)/100000
print C# Prints 980
Вы также можете использовать Decimal следующим образом:
from decimal import *
getcontext().prec = 6
Decimal(1) / Decimal(7)
# Results in 6 precision -> Decimal('0.142857')
getcontext().prec = 28
Decimal(1) / Decimal(7)
# Results in 28 precision -> Decimal('0.1428571428571428571428571429')
getcontext().prec = 6 работает только в рамках функции или во всех местах?
Контексты - это среда для арифметических операций. Они регулируют точность, устанавливают правила округления, определяют, какие сигналы обрабатываются как исключения, и ограничивают диапазон показателей. У каждого потока есть свой текущий контекст @JulioMarins
Я считаю, что самый простой подход - использовать функцию format().
Например:
a = 13.949999999999999
format(a, '.2f')
13.95
В результате получается число с плавающей запятой в виде строки, округленной до двух десятичных знаков.
Чтобы округлить число до разрешения, лучше всего использовать следующий способ, который может работать с любым разрешением (0,01 для двух знаков после запятой или даже с другими шагами):
>>> import numpy as np
>>> value = 13.949999999999999
>>> resolution = 0.01
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
13.95
>>> resolution = 0.5
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
14.0
у меня не работает на python 3.4.3 и numpy 1.9.1? >>> import numpy as np >>> res = 0.01 >>> value = 0.184 >>> np.round (value / res) * res 0.17999999999999999
Ищу документацию, я вижу, что проблема связана с точностью / точностью numpy.round. Поэтому перед умножением с разрешением необходимо определить его как int. Я обновил код. Спасибо тебе за это!
Единственное, что необходимо - это преобразовать результат numpy.float64 из np.round в float или просто использовать round(value, 2). Не существует действительного номера IEEE 754 между 13.949999999999999 (= 1395 / 100.) и 3.950000000000001 (= 1395 * .01). Как вы думаете, почему ваш метод самый лучший? Исходное значение 13.949999999999999289 (= value = round (value, 2)) даже более точное, чем ваше 13.95000000000000178 (напечатанное np.float96). Дополнительная информация также для numpy теперь добавлена в мой ответ, который вы, вероятно, проголосовали против по ошибке. Изначально речь не шла о numpy.
@hynekcer Не думаю, что мой ответ лучший. Просто хотел добавить пример предельного числа с плавающей запятой до n десятичных знаков, но ближайшего к определенному разрешению. Как вы сказали, я проверил, что вместо int вы также можете использовать float для примера @szeitlin. Спасибо за дополнительный комментарий. (Извините, но я не голосовал против вас)
Добавление совершенно новой зависимости для числовой обработки (панд) - это «лучший способ»?
Я использую метод нарезки строк. Это относительно быстро и просто.
Сначала преобразуйте float в строку, выберите желаемую длину.
float = str(float)[:5]
В единственной строке выше мы преобразовали значение в строку, а затем сохранили строку только с ее первыми четырьмя цифрами или символами (включительно).
Надеюсь, это поможет!
Пожалуйста, не публикуйте одинаковые ответы на несколько вопросов.
Ничего себе ... tdh ... Пожалуйста, никогда не создавайте никаких бухгалтерских программ ... Что произойдет, если число окажется 113.94 ?? это приведет к 113.9 ... оставив 0,04 пропущенным .... Также на это уже есть ответы более 5 лет назад ....
Проблема округления ввода / вывода была окончательно решен Python 2.7.0 и 3.1.
Правильно округленное число может быть обратимо преобразовано туда и обратно: str -> float() -> repr() -> float() ... или Decimal -> float -> str -> Decimal
Тип Decimal больше не нужен для хранения.
(Естественно, может возникнуть необходимость округлить результат сложения или вычитания округленных чисел, чтобы исключить накопленные последние битовые ошибки. Явная десятичная арифметика может быть удобна, но преобразование в строку с помощью str() (то есть с округлением до 12 допустимо цифр) обычно бывает достаточно, если не требуется предельной точности или чрезмерного количества последовательных арифметических операций.)
Бесконечный тест:
import random
from decimal import Decimal
for x in iter(random.random, None): # Verify FOREVER that rounding is fixed :-)
assert float(repr(x)) == x # Reversible repr() conversion.
assert float(Decimal(repr(x))) == x
assert len(repr(round(x, 10))) <= 12 # Smart decimal places in repr() after round.
if x >= 0.1: # Implicit rounding to 12 significant digits
assert str(x) == repr(round(x, 12)) # by str() is good enough for small errors.
y = 1000 * x # Decimal type is excessive for shopping
assert str(y) == repr(round(y, 12 - 3)) # in a supermaket with Python 2.7+ :-)
См. Четвертый абзац Примечания к выпуску Python 2.7 - другие языковые изменения:
Conversions between floating-point numbers and strings are now correctly rounded on most platforms. These conversions occur in many different places: str() on floats and complex numbers; the float and complex constructors; numeric formatting; serializing and de-serializing floats and complex numbers using the
marshal,pickleandjsonmodules; parsing of float and imaginary literals in Python code; and Decimal-to-float conversion.Related to this, the repr() of a floating-point number x now returns a result based on the shortest decimal string that’s guaranteed to round back to x under correct rounding (with round-half-to-even rounding mode). Previously it gave a string based on rounding x to 17 decimal digits.
Больше информации: Форматирование float до Python 2.7 было аналогично текущему numpy.float64. Оба типа используют одинаковую 64-битную двойную точность IEEE 754 с 52-битной мантиссой. Большое различие состоит в том, что np.float64.__repr__ часто форматируется с чрезмерным десятичным числом, чтобы ни один бит не мог быть потерян, но действительного числа IEEE 754 между 13.949999999999999 и 13.950000000000001 не существует. Результат нехороший, и преобразование repr(float(number_as_string)) необратимо с помощью numpy. С другой стороны: float.__repr__ отформатирован так, что важна каждая цифра; последовательность без пропусков и преобразование обратимое. Проще говоря: если у вас, возможно, есть число numpy.float64, преобразуйте его в обычное число с плавающей запятой, чтобы он был отформатирован для людей, а не для числовых процессоров, иначе с Python 2.7+ больше ничего не потребуется.
Почему проголосовали против? Речь шла о Python float (с двойной точностью) и обычном round, а не о numpy.double и его преобразовании в строку. Обычное округление в Python действительно невозможно сделать лучше, чем в Python 2.7. Большинство ответов было написано до 2.7, но они устарели, хотя изначально были очень хорошими. Это причина моего ответа.
53 бита, когда вы включаете «скрытый бит», который неявно является 1, за исключением «постепенного потери значимости».
Это не ошибка раунда, это ошибка дисплея.
Да, это хорошо известно. Однако мне не хватает контекста, если вы возражаете против чего-либо в примечаниях к выпуску Python 2.7 или в моем тексте или против чего-либо вообще. Сложнее, чем было необходимо, цель этого вопроса. Следует добавить, что преобразование из строки в число с плавающей запятой также было исправлено в Python 2.7 из-за ошибка округления на некоторых 32-битных чипах Intel и что «Функция round () также правильно округлена сейчас». (Примечания к выпуску - функции 3.1 перенесены в 2.7). Вы согласны?
Ой, это был a*b против b*a. Спасибо за ссылки - Ностальгия.
Образец кода не работает как для Python 2.7.13, так и для Python 3.5.3.
@ Жером. Спасибо. Исправлено сейчас. У меня была опечатка x вместо y, когда я объединил два теста в этот пример для разного порядка величины.
Встроенный round() отлично работает с Python 2.7 или новее.
Пример:
>>> round(14.22222223, 2)
14.22
Проверьте документация.
Итак, я должен понимать, что это ошибка Python 2.7? Почему такая фундаментальная функция дает разные результаты в версиях 2.7 и 3?
но round(2.16, 1) дает 2.2, почему python просто предлагает функцию truncate
Например, если вы попытаетесь округлить значение 2,675 до двух десятичных знаков, вы получите >>> round(2.675, 2) 2.67docs.python.org/2/tutorial/floatingpoint.html
Со страницы документации Python 3: Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float.
Обратите внимание, что если вы попытаетесь использовать этот метод для печати числа, такого как 1.00000, он распечатает только 1.0, независимо от того, сколько десятичных знаков вы укажете.
@RichardDally Спасибо за столь необходимую информацию. Не могли бы вы объяснить, почему "большинство десятичных дробей не могут быть представлены в точности как число с плавающей запятой"?
Использовать
print"{:.2f}".format(a)
вместо
print"{0:.2f}".format(a)
Потому что последнее может привести к ошибкам вывода при попытке вывода нескольких переменных (см. Комментарии).
Это нонсенс. Два приведенных оператора ведут себя идентично в Python 2.7, и только второй оператор действителен в Python 2.6. (Ни один из операторов не действителен в Python 3 или Python <2.6.) У первой формы нет никаких преимуществ, кроме краткости.
Я имею в виду, что печать "{0: .2f} {0: .2f}". Format (a, b) приведет к ошибке при выводе - он будет выводить значение 'a' дважды. При печати "{:. 2f} {: .2f}". Format (a, b) будет выводить значения 'a' и 'b'.
Для Python 3 вам просто нужно добавить скобки print (...). И в них все, что я написал, правильно.
"Я имею в виду, напечатайте" {0: .2f} {0: .2f} ". Format (a, b) приведет к ошибке при выводе". Ах. Что ж, это совсем другое заявление! Может стоит отредактировать свой ответ? (Что, например, означает «вызвать ошибку» в текущем ответе? Можете ли вы привести пример случая, когда второй оператор вызывает исключение, а первый - нет?)
Вы будете после print ("{0: .2f} {1: .2f}". Format (a, b)), если у вас есть две переменные
orig_float = 232569 / 16000.0
14.5355625
short_float = float("{:.2f}".format(orig_float))
14.54
Кажется, здесь никто еще не упомянул об этом, поэтому позвольте мне привести пример в формате f-string / template-string Python 3.6, который, на мой взгляд, очень аккуратен:
>>> f'{a:.2f}'
Он также хорошо работает с более длинными примерами, с операторами и не нуждающимися в скобках:
>>> print(f'Completed in {time.time() - start:.2f}s')
это конец 2020 года, а это все еще намного ниже
Как отметил @Matt, Python 3.6 предоставляет f-строки, и они также могут использовать вложенные параметры:
value = 2.34558
precision = 2
width = 4
print(f'result: {value:{width}.{precision}f}')
который отобразит result: 2.35
В Python 2.7:
a = 13.949999999999999
output = float("%0.2f"%a)
print output
Это совсем не помогает. output имеет значение точно так же как a, поэтому вы могли бы написать print a вместо print output в последней строке.
@MarkDickinson Не могли бы вы попробовать еще раз. Потому что он работает в моем компиляторе, как и ожидалось.
Вы упускаете мою точку зрения. Да, ваш код печатает 13.95. Но то же самое делает print a для этого конкретного значения a в Python 2.7, поэтому не совсем понятно, в чем заключалась цель этапа форматирования.
@MarkDickinson Я отредактировал код. Я согласен с тем, что «print a» выводит то же значение, что и «print output». Но если вы сравните «a == output», результатом будет «False», потому что на этапе форматирования плавающее значение «a» округляется до двух десятичных знаков.
Вы действительно пробовали a == output для кода, который вы показываете? Он дает мне True, и я подозреваю, что это дает и вам.
@MarkDickinson Для a=13.949999999999999 я получаю Правда. Для a=13.9499999 я получаю Ложь. Я немного запутался !!!
from decimal import Decimal
def round_float(v, ndigits=2, rt_str=False):
d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str:
return v_str
return Decimal(v_str)
Полученные результаты:
Python 3.6.1 (default, Dec 11 2018, 17:41:10)
>>> round_float(3.1415926)
Decimal('3.14')
>>> round_float(3.1445926)
Decimal('3.14')
>>> round_float(3.1455926)
Decimal('3.15')
>>> round_float(3.1455926, rt_str=True)
'3.15'
>>> str(round_float(3.1455926))
'3.15'
Это просто как 1,2,3:
используйте модуль десятичный для быстрой арифметики правильно округленных десятичных чисел с плавающей запятой:
d = десятичный (10000000.0000009)
для достижения округления:
d.quantize(Decimal('0.01'))
будет результат с Decimal('10000000.00')
def round_decimal(number, exponent='0.01'):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(exponent))
ИЛИ ЖЕ
def round_decimal(number, decimal_places=2):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(10) ** -decimal_places)
PS: критика других: форматирование не округление.
Вы можете использовать оператор формат для округления значения до 2 десятичных знаков в python:
print(format(14.4499923, '.2f')) // output is 14.45
Это возвращает строку
А как насчет такой лямбда-функции:
arred = lambda x,n : x*(10**n)//1/(10**n)
Таким образом, вы могли просто сделать:
arred(3.141591657,2)
и получить
3.14
Используйте комбинацию объекта Decimal и метода round ().
Python 3.7.3
>>> from decimal import Decimal
>>> d1 = Decimal (13.949999999999999) # define a Decimal
>>> d1
Decimal('13.949999999999999289457264239899814128875732421875')
>>> d2 = round(d1, 2) # round to 2 decimals
>>> d2
Decimal('13.95')
lambda x, n: int (x * 10п + 0,5) / 10n работал у меня многие лет на многих языках.
Ответы, которые я видел, не работали со случаем float (52.15). После некоторых тестов я нашел решение, которое я использую:
import decimal
def value_to_decimal(value, decimal_places):
decimal.getcontext().rounding = decimal.ROUND_HALF_UP # define rounding method
return decimal.Decimal(str(float(value))).quantize(decimal.Decimal('1e-{}'.format(decimal_places)))
(Преобразование «значения» в число с плавающей запятой, а затем в строку очень важно, таким образом, «значение» может иметь тип с плавающей запятой, десятичное, целое или строковое!)
Надеюсь, это кому-нибудь поможет.
У нас есть несколько вариантов для этого: Опция 1:
x = 1.090675765757
g = float("{:.2f}".format(x))
print(g)
Вариант 2: Встроенный round () поддерживает Python 2.7 или новее.
x = 1.090675765757
g = round(x, 2)
print(g)
В вопросе конкретно сказано, что круглый метод не делает то, что хочет. Проверьте этот ответ для получения дополнительной информации о том, почему это
float_number = 12.234325335563
round(float_number, 2)
Это вернется;
12.23
функция round принимает два аргумента; Число для округления и количество возвращаемых десятичных знаков. Здесь я вернул 2 десятичных знака.
Но как вы получили дополнительный 0, если у нас есть, скажем, 0,093? Это дает мне 0,1 в качестве ответа
Если вы вернете 2 десятичных разряда или вообще на 1 место больше, чем количество нулей, присутствующих в десятичной части с левой стороны, тогда вы получите правильный результат, как хотите. Например, если вы примените просто мой ответ к числу 0,093, он вернет 0,09, но если вы хотите получить только 1 десятичный знак, тогда, конечно, он вернет 0,1, поскольку 0,0 полностью неверен. (и мой код работает таким же образом. Возможно, вы хотите получить только 1 десятичный разряд. Если если вы хотите получить более точные результаты, необходимо увеличить количество десятичных знаков.)
Неправда, что он вернет десятичное число, согласно документации `Возвращаемое значение является целым числом, если ndigits опущено или None. В противном случае возвращаемое значение имеет тот же тип, что и число. ndigits может быть отрицательным.
Если вы хотите обрабатывать деньги, используйте модуль python десятичный
from decimal import Decimal, ROUND_HALF_UP
# amount can be integer, string, tuple, float, or another Decimal object
def to_money(amount) -> Decimal:
money = Decimal(amount).quantize(Decimal('.00'), rounding=ROUND_HALF_UP)
return money