Как округлить до 2 десятичных с Python?

255

Я получаю много десятичных знаков при выводе этого кода (конвертер Фаренгейта в Цельсий).

Мой код в настоящее время выглядит так:

def main():
    printC(formeln(typeHere()))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(answer)
    print "\nYour Celsius value is " + answer + " C.\n"



main()

Итак, мой вопрос, как мне сделать программу вокруг каждого ответа до 2-го знака после запятой?

Dolcens
источник
7
Небольшое замечание относительно вашего кода. Нет смысла сохранять значение по Фаренгейту глобальным, достаточно (и лучше) передать его в качестве параметра вашим функциям. Итак, удалите «глобальную линию Фаренгейта». В функции formeln переименуйте параметр в функцию «Fahreinheit» (Fahreinheit). Что касается округления, вы можете просто использовать параметры «%» для отображения только первых 2 цифр, и для этих цифр оно должно быть округлено. Не влияет на количество цифр в формуле в формуле.
Ариэли

Ответы:

443

Вы можете использовать roundфункцию, которая принимает в качестве первого аргумента число, а второй аргумент - точность после десятичной точки.

В вашем случае это будет:

answer = str(round(answer, 2))
rolisz
источник
21
Это называется округлением банкиров. Это округляется к четному числу. Это стандарт IEEE 754 для чисел с плавающей запятой. en.wikipedia.org/wiki/Rounding#Round_half_to_even
rolisz
37
Я не уверен, что побудило людей высказаться выше. Для сведения, тот факт, что round(2.675, 2)дает, 2.67а не 2.68имеет ничего общего с округлением банкира.
Марк Дикинсон
3
примечание : это меняет значение ответа. Если вы просто хотите округлить для отображения, ответьте на вопрос @Johnsyweb - stackoverflow.com/a/20457284/1498405
hardmooth
4
@Johnsyweb Я пробую это сегодня, через год после оригинального сообщения, и это выглядит так, как ожидалось. Кажется, раунд () эволюционировал со временем. Смотрите ниже: раунд (1.379, 2) -> 1.38 раунд (1.372, 2) -> 1.37 раунд (1.375, 2) -> 1.38
NightFurry
83

Используя str.format()«ы синтаксис для отображения answer с двумя десятичными знаками (без изменения базовой стоимости answer):

def printC(answer):
    print("\nYour Celsius value is {:0.2f}ºC.\n".format(answer))

Куда:

  • :вводит спецификацию формата
  • 0 разрешает добавление нуля с учетом знака для числовых типов
  • .2устанавливает точность в2
  • f отображает номер как число с фиксированной точкой
Johnsyweb
источник
3
Это самый полезный ответ IMO - сохраняет фактическое значение без изменений и прост в реализации! Спасибо!
BrettJ
Не знаю почему, но формат {{0.2f} '. (0.5357706) дает мне 0.54 (python 3.6)
Noam Peled
3
@NoamPeled: Почему бы и нет? 0.5357...ближе к 0.54чем 0.53, поэтому 0.54имеет смысл округлять до .
ShadowRanger
"{:0.2f}".format(1.755)-> 1,75 "{:0.2f}".format(1.7551)-> 1,76 - Тем не менее, я бы ожидал равным 1,76.
Джанотан
(Версия Python: 3.6.10)
января
48

Большинство предложенных ответов roundили format. roundиногда округляется, и в моем случае мне нужно, чтобы значение моей переменной было округлено, а не просто отображено как таковое.

round(2.357, 2)  # -> 2.36

Я нашел ответ здесь: Как мне округлить число с плавающей запятой до определенного десятичного знака?

import math
v = 2.357
print(math.ceil(v*100)/100)  # -> 2.36
print(math.floor(v*100)/100)  # -> 2.35

или:

from math import floor, ceil

def roundDown(n, d=8):
    d = int('1' + ('0' * d))
    return floor(n * d) / d

def roundUp(n, d=8):
    d = int('1' + ('0' * d))
    return ceil(n * d) / d
s4w3d0ff
источник
1
Я проголосовал - это то, что я искал; Мне нравится ваша работа с python-poloniex: D
Skylar Saveland
2
«значения округлены до ближайшего кратного 10 к степени минус цифра;» docs.python.org/3/library/functions.html#round так что нет, округление не всегда округляется , например,round(2.354, 2) # -> 2.35
Пит Киркхам
@PeteKirkham ты прав, я отредактировал свой ответ, чтобы сделать его более понятным и точным.
s4w3d0ff
2
-0,54 является правильным ответом для округления -0,5357706 вниз, потому что это отрицательное число, -0,54 <-0,53
s4w3d0ff
2
Я бы использовал 10**dвместо int('1' + ('0' * d)).
Джонатон Рейнхарт
11
float(str(round(answer, 2)))
float(str(round(0.0556781255, 2)))
Mahadi
источник
8

Вы хотите округлить свой ответ.

round(value,significantDigit)Это обычное решение для этого, однако иногда это не работает так, как можно было бы ожидать с математической точки зрения, когда цифра, непосредственно уступающая (слева от) цифре, к которой вы округляете, имеет5 .

Вот несколько примеров такого непредсказуемого поведения:

>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01

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

>>> round(0.075,2)

0.07

>>> round(0.075+10**(-2*6),2)

0.08

Ага! На основании этого мы можем сделать функцию ...

def roundTraditional(val,digits):
   return round(val+10**(-len(str(val))-1), digits)

По сути, это добавляет действительно маленькое значение к строке, чтобы заставить ее правильно округляться в непредсказуемых случаях, когда она обычно не работает с roundфункцией, когда вы этого ожидаете. Удобное значение для добавления - это 1e-XгдеX длина номер строки , которую вы пытаетесь использовать roundна плюс1 .

Подход использования 10**(-len(val)-1)был преднамеренным, так как это наибольшее небольшое число, которое вы можете добавить, чтобы форсировать сдвиг, и при этом гарантировать, что добавляемое вами значение никогда не изменит округления, даже если десятичная дробь .отсутствует. Я мог бы использовать только 10**(-len(val))с условным if (val>1)вычитать1 больше ... но проще всегда всегда вычитать, 1поскольку это не сильно изменит применимый диапазон десятичных чисел, который этот обходной путь может правильно обработать. Этот подход потерпит неудачу, если ваши значения достигнут пределов типа, это не удастся, но почти для всего диапазона допустимых десятичных значений это должно работать.

Таким образом, готовый код будет выглядеть примерно так:

def main():
    printC(formeln(typeHere()))

def roundTraditional(val,digits):
    return round(val+10**(-len(str(val))-1))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(roundTraditional(answer,2))
    print "\nYour Celsius value is " + answer + " C.\n"

main()

... должен дать вам ожидаемые результаты.

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


Изменить: Спасибо Blckknght за указание, что 5крайний случай происходит только для определенных значений здесь .

Джейсон Р. Мик
источник
6

Просто используйте форматирование с% .2f, которое дает округление до 2 десятичных знаков.

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer
Сантош Гимир
источник
4

Вы можете использовать оператор форматирования строки python "%". «% .2f» означает 2 цифры после десятичной точки.

def typeHere():
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(Fahrenheit):
    Celsius = (Fahrenheit - 32.0) * 5.0/9.0
    return Celsius

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer

def main():
    printC(formeln(typeHere()))

main()

http://docs.python.org/2/library/stdtypes.html#string-formatting

Ариели
источник
4

Вы можете использовать оператор округления до 2 десятичных

num = round(343.5544, 2)
print(num) // output is 343.55
Асад Манзур
источник
3

Вы можете использовать функцию округления.

round(80.23456, 3)

даст вам ответ 80.234

В вашем случае используйте

answer = str(round(answer, 2))
Сатьяки Саньял
источник
2

Если вам нужно избежать проблемы с плавающей запятой с при округлении чисел для учета, вы можете использовать numpy round.

Вам нужно установить NumPy:

pip install numpy

и код:

import numpy as np

print(round(2.675, 2))
print(float(np.round(2.675, 2)))

печать

2.67
2.68

Вы должны использовать это, если вы управляете деньгами с законным округлением.

Сэмюэль Даузон
источник
1

Вот пример, который я использовал:

def volume(self):
    return round(pi * self.radius ** 2 * self.height, 2)

def surface_area(self):
    return round((2 * pi * self.radius * self.height) + (2 * pi * self.radius ** 2), 2)
Патрик Хилл
источник
1

Не знаю почему, но формат {: 0.2f}. (0.5357706) дает мне 0.54. Единственное решение, которое работает для меня (Python 3.6), заключается в следующем:

def ceil_floor(x):
    import math
    return math.ceil(x) if x < 0 else math.floor(x)

def round_n_digits(x, n):
    import math
    return ceil_floor(x * math.pow(10, n)) / math.pow(10, n)

round_n_digits(-0.5357706, 2) -> -0.53 
round_n_digits(0.5357706, 2) -> 0.53
Ноам Пелед
источник
Это усечение, а не округление.
ShadowRanger