Python Как создать 2-значный после точки плавать? [Дубликат]

Строки в Java неизменяемы. Это означает, что всякий раз, когда вы пытаетесь изменить / изменить строку, вы получаете новый экземпляр. Вы не можете изменить исходную строку. Это сделано для того, чтобы эти экземпляры строк могли кэшироваться. Типичная программа содержит множество ссылок на строки и кеширование этих экземпляров, что может уменьшить объем памяти и увеличить производительность программы.

При использовании оператора == для сравнения строк вы не сравниваете содержимое строки , но фактически сравнивают адрес памяти. Если они равны, в противном случае они вернут true и false. Если значение равно в строке, сравнивает содержимое строки.

Итак, вопрос в том, что все строки кэшируются в системе, как получается == возвращает false, тогда как equals возвращает true? Ну, это возможно. Если вы создадите новую строку, например String str = new String("Testing"), вы создадите новую строку в кеше, даже если в кеше уже содержится строка с тем же содержимым. Короче говоря, "MyString" == new String("MyString") всегда будет возвращать false.

Java также говорит о функции intern (), которая может использоваться в строке, чтобы сделать ее частью кеша, поэтому "MyString" == new String("MyString").intern() вернет true.

Примечание: == оператор намного быстрее, чем равен только потому, что вы сравниваете два адреса памяти, но вы должны быть уверены, что код не создает новые экземпляры String в коде. В противном случае вы столкнетесь с ошибками.

1135
задан ShadowRanger 29 September 2017 в 04:42
поделиться

7 ответов

Я считаю, что самый простой подход заключается в использовании функции format().

Например:

a = 13.949999999999999
format(a, '.2f')

13.95

Это создает число с плавающей точкой в ​​виде строки, округленной до двух десятичных знаков точек.

119
ответ дан Armali 16 August 2018 в 01:04
поделиться
  • 1
    обратите внимание, что тип возвращаемого значения будет строкой. это не то, что я искал. – Dap 19 April 2016 в 18:14
  • 2
    @Dap float(format(a, '.2f')) – T. Webster 22 July 2017 в 20:00

Никто здесь, похоже, не упомянул об этом, поэтому позвольте мне привести пример в формате f-string / template-string Python 3.6, который, я думаю, красиво опрятен:

>>> f'{a:.2f}'

It хорошо работает и с более длинными примерами, с операторами и не нуждающимися в парсе:

>>> print(f'Completed in {time.time() - start:.2f}s')
11
ответ дан Matt Fletcher 16 August 2018 в 01:04
поделиться
orig_float = 232569 / 16000.0

14.5355625

short_float = float("{:.2f}".format(orig_float)) 

14.54

4
ответ дан MikeL 16 August 2018 в 01:04
поделиться

Чтобы округлить число до разрешения, наилучшим способом является следующий, который может работать с любым разрешением (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
1168
ответ дан Peter Mortensen 16 August 2018 в 01:04
поделиться
  • 1
    Это даст вам строку. Не число. – Onur Yıldırım 24 March 2013 в 06:04
  • 2
    @Christian Существует фундаментальное различие между сохраненным значением и тем, как вы отображаете это значение. Форматирование вывода должно позволять вам добавлять дополнения по мере необходимости, а также добавлять разделители запятой и т. Д. – Basic 8 April 2013 в 12:03
  • 3
    Но будьте осторожны, значение a по-прежнему является неточным поплавком. Посмотрите здесь - repl.it/LJs (нажмите «Запустить сеанс» в верхней части правой части). – lifebalance 2 October 2013 в 20:23
  • 4
    стоит упомянуть, что "%.2f" % round(a,2) вы можете добавить не только в printf, но и в таких вещах, как str() – andilabs 1 November 2013 в 03:15
  • 5
    Если вы пойдете с таким подходом, вы должны добавить 0.5 для более точного представления. int (a * 100 + 0,5) / 100,0; Использование math.ceil - еще один вариант. – arhuaco 8 November 2013 в 02:11
  • 6
    Как вы представляете целое число? Если я использую «{i3}» .format (numvar), я получаю сообщение об ошибке. – skytux 12 December 2013 в 17:29
  • 7
    Вот что я имею в виду: если numvar=12.456, то "{:.2f}".format(numvar) дает 12.46, но "{:2i}".format(numvar) дает ошибку, и я ожидаю 12. – skytux 12 December 2013 в 17:47
  • 8
    почему люди всегда принимают валюту при округлении с плавающей запятой? иногда вы просто хотите работать с меньшей точностью. – worc 12 January 2014 в 01:56
  • 9
    @ShashankSawant: Ну, с одной стороны, ответ, представленный не круглый, он усекает. Предложение добавить половину в конец будет раундом, но тогда нет никакой пользы для этого, просто используя функцию round в первую очередь. С другой стороны, поскольку это решение все еще использует с плавающей точкой, исходная проблема OP остается, даже для «исправленной» версии этого «решения». – John Y 17 June 2014 в 23:54
  • 10
    для добавления запятых также вы можете '{0:,.2f}'.format(1333.949999999), который печатает '1,333.95'. – Stephen Blum 20 June 2014 в 03:41
  • 11
    @ OnurYıldırım: да, но вы можете обернуть его с помощью float(); float("{0:.2f}".format(13.9499999)) – Jossef Harush 17 August 2014 в 14:22
  • 12
    @JossefHarush вы можете обернуть его с помощью float (), но вы ничего не получили. Теперь у вас есть поплавок снова, с той же неточностью. 13.9499999999999 и 13.95 являются одинаковыми поплавками. – Ned Batchelder 17 August 2014 в 14:52
  • 13
    @NedBatchelder: Я согласен, что они равны, но это ограничивает float до двух десятичных знаков :) – Jossef Harush 17 August 2014 в 15:09
  • 14
    -1, это просто лишняя повторная реализация функции round (которая использовалась в вопросе). – interjay 12 September 2014 в 23:55
  • 15
    @interjay, который необходим, если round() не работает как упомянутый OP. – Pithikos 18 February 2015 в 14:28
  • 16
    не работает для меня на python 3.4.3 и numpy 1.9.1? & GT; & GT; & GT; import numpy как np & gt; & gt; & gt; & gt; & gt; res = 0,01 & gt; & gt; & gt; & gt; значение = 0,184 & gt; & gt; & gt; np.round (значение / res) * res 0.17999999999999999 – szeitlin 11 April 2016 в 16:34
  • 17
    В поисках документации я вижу, что проблема исходит из точности numpy.round. Поэтому требуется определить его как int перед умножением с разрешением. Я обновил код. Спасибо вам за это! – iblasi 13 April 2016 в 16:28
  • 18
    Почему вниз вниз? Вопрос был о Python float (двойная точность) и нормальном round, а не о numpy.double и его преобразовании в строку. Обычное округление Python действительно не может быть сделано лучше, чем в Python 2.7. Большинство ответов написано до 2.7, но они устарели, хотя изначально они были очень хорошими. Это и есть причина моего ответа. – hynekcer 15 April 2016 в 11:02
  • 19
    Необходимо только преобразовать 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 теперь добавлена ​​к моему ответу , который вы, вероятно, по ошибке проигнорировали. Первоначально это было не так. – hynekcer 15 April 2016 в 13:04
  • 20
    @hynekcer Я не думаю, что мой ответ лучший. Просто хотел добавить пример limit float в n десятичных знаков, но ближайший из определенного разрешения. Я проверил, как вы сказали, что вместо int вы также можете использовать float для примера @szeitlin. Спасибо за ваш дополнительный комментарий. (Извините, но я не спустил вас вниз) – iblasi 15 April 2016 в 20:49
  • 21
    @radtek: Вам нужно понять, что двоичное значение (типа float) является всего лишь ближайшей доступной аппроксимацией десятичного числа (с которым вы знакомы как человек). Нет такого (конечно-представимого) двоичного значения, равного 0.245. Это просто не существует, и математически не может существовать . Бинарное значение, которое ближе всего к 0.245, немного меньше 0.245, поэтому, естественно, оно округляется вниз. Аналогично, в двоичном коде нет такой величины, как 0.225, но двоичное значение, которое ближе всего к 0.225, немного больше 0.225, поэтому, естественно, оно округляется. – John Y 14 June 2016 в 19:06
  • 22
    @radtek: Вы буквально попросили объяснения. Самое простое решение - действительно использовать Decimal, и это было одним из решений, представленных в этом ответе. Другим было преобразование ваших величин в целое число и использование целочисленной арифметики. Оба эти подхода также появились в других ответах и ​​комментариях. – John Y 15 June 2016 в 19:45
  • 23
    53 бит, когда вы включаете «скрытый бит», который неявно 1, за исключением «постепенного переполнения». – Rick James 17 May 2017 в 04:16
  • 24
    Это не круговая ошибка, это ошибка дисплея. – Rick James 17 May 2017 в 04:22
  • 25
    Да, это хорошо известно. Я пропускаю, однако, контекст, если вы возражаете против чего-то в примечаниях к выпуску Python 2.7 Release или в моем тексте или вообще ничего. Это сложнее, чем было необходимо для цели этого вопроса. Следует добавить, что также преобразование из строки в float было исправлено в Python 2.7 из-за ошибки округления на некоторых 32-разрядных чипах Intel , и что теперь функция round () также правильно округлены. & quot; ( Примечания к выпуску - 3.1 функции, переданные до 2.7 ). Вы согласны? – hynekcer 17 May 2017 в 09:26
  • 26
    К сожалению, это было a*b vs b*a. Спасибо за ссылки - ностальгия. – Rick James 17 May 2017 в 20:11
  • 27
    Так я должен понять, что это Python 2.7 сбой? Почему такая фундаментальная функция дает разные результаты от v 2.7 до v 3? – Michael Mügge 2 September 2017 в 23:50
  • 28
    getcontext().prec = 6 работает только для сферы действия или всех мест? – Julio Marins 4 October 2017 в 20:12
  • 29
    Контексты являются средами для арифметических операций. Они регулируют точность, устанавливают правила округления, определяют, какие сигналы обрабатываются как исключения, и ограничивают диапазон для показателей. Каждый поток имеет свой текущий контекст @JulioMarins – Siamand Maroufi 4 October 2017 в 20:32
  • 30
    но round(2.16, 1) дают 2.2, почему python просто предлагает функцию truncate – jiamo 8 January 2018 в 04:31
  • 31
    Это также работает в Python 2.7. Лучший ответ на этот вопрос, на мой взгляд. – alwbtc 25 January 2018 в 11:32
  • 32
    Это нонсенс. Оба приведенных оператора ведут себя одинаково на Python 2.7, и только второй оператор действителен на Python 2.6. (Ни один из операторов не действителен в Python 3 или Python & lt; 2.6.) Первая форма не имеет преимуществ, кроме краткости. – Mark Dickinson 28 January 2018 в 18:56
  • 33
    Я имею в виду, что print & quot; {0: .2f} {0: .2f} ".format (a, b) приведет к ошибке в выходе - он выведет значение 'a' дважды. В то время как print & quot; {:. 2f} {: .2f} ".format (a, b) выдаст значения 'a' и 'b'. – Alexey Antonenko 1 February 2018 в 18:30
  • 34
    Для Python 3 вам просто нужно добавить скобки print (...). И в них все, что я написал, правильно. – Alexey Antonenko 1 February 2018 в 18:31
  • 35
    «Я имею в виду, print & quot; {0: .2f} {0: .2f}» .format (a, b) приведет к ошибке в выходе ». Ах. Ну, это совсем другое заявление! Может быть, вы должны отредактировать свой ответ? (Например, что означает «повышение ошибки» в текущем ответе? Можете ли вы привести пример случая, когда второй оператор вызывает исключение, но первое не делает?) – Mark Dickinson 1 February 2018 в 19:34
  • 36
    Вы будете после печати («{0: .2f} {1: .2f}» .format (a, b)), если у вас есть две переменные – Hovo 11 February 2018 в 00:12
  • 37
    Это совсем не помогает. output имеет то же самое значение как a, поэтому вы могли бы также записать print a вместо print output в последней строке. – Mark Dickinson 26 May 2018 в 06:12

Метод, который я использую, - это метод нарезания строк. Это относительно быстро и просто.

Сначала преобразуем float в строку, выберите длину, в которой вы хотели бы быть.

float = str(float)[:5]

В одной строке выше мы 'преобразовал значение в строку, а затем сохранил строку только до ее первых четырех цифр или символов (включительно).

Надеюсь, что это поможет!

-12
ответ дан tdh 16 August 2018 в 01:04
поделиться
  • 1
    Пожалуйста, не отправляйте идентичные ответы на несколько вопросов. – vaultah 31 December 2015 в 09:18
  • 2
    WOW ... tdh ... Пожалуйста, никогда не делайте никаких учетных программ ... Что произойдет, если число будет 113.94 ?? это привело бы к 113,9 ... оставив 0.04 пропавших без вести .... Также у этого уже есть ответы более 5 лет назад .... – Mayhem 8 January 2016 в 04:33

Как отметил @Matt, Python 3.6 предоставляет f-строки , и они также могут использовать вложенные параметры :

value = 2.34558
precision = 2
width = 4

print(f'result: {value:{width}.{precision}f}')

, которые будут дисплей result: 2.35

7
ответ дан toto_tico 16 August 2018 в 01:04
поделиться

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

>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'

И, наконец, хотя, возможно, самое главное, если вы хотите точная математика, тогда вы не хотите плавать вообще. Обычный пример - это деньги и хранить центы как целое.

85
ответ дан user 16 August 2018 в 01:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: