【问题标题】:How to round to 2 decimals with Python? [duplicate]如何用 Python 舍入到 2 位小数? [复制]
【发布时间】:2022-12-20 00:11:57
【问题描述】:

我在这段代码的输出中得到了很多小数(华氏度到摄氏度转换器)。

我的代码目前看起来像这样:

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()

所以我的问题是,如何让程序将每个答案四舍五入到小数点后第二位?

【问题讨论】:

  • 关于您的代码的一个小评论。没有理由将华氏温度值作为全局值保存,将其作为参数传输到您的函数就足够了(而且更好)。因此,删除“全球华氏度”行。在 formeln 函数中,将参数重命名为函数“Fahreinheit”formeln(Fahreinheit)。至于四舍五入,可以直接用“%”参数,只显示前2位,这几位要四舍五入。 formeln 中公式中提供的位数没有影响。

标签: python rounding


【解决方案1】:

您可以使用 round 函数,它的第一个参数是数字,第二个参数是小数点后的精度。

在您的情况下,它将是:

answer = str(round(answer, 2))

【讨论】:

【解决方案2】:

使用str.format()syntax展示answer 保留两位小数(不改变 answer 的基础值):

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

在哪里:

  • :介绍format spec
  • 0 为数字类型启用符号感知零填充
  • .2precision 设置为 2
  • f 将数字显示为定点数

【讨论】:

  • 这是 IMO 最有用的答案 - 保持实际值不变并且易于实施!谢谢!
  • @NoamPeled:为什么不呢? 0.5357...0.53 更接近 0.54,因此四舍五入到 0.54 是有道理的。
  • @Janothan 浮点值不精确。试试"{:0.20f}".format(1.755),你就会明白为什么带两位小数的值显示为1.75
  • 这里的符号感知零填充是什么意思?我知道如果数字不够长,它将用前导零填充,但由于这里没有最小长度要求(如 {:05.2f}),零有什么作用?
  • @jackz314 在我写下这个答案 6.5 年(以及许多 Python 版本)之后,我忘记了为什么我认为零值得包括在内。
【解决方案3】:

大多数答案建议roundformatround 有时会四舍五入,就我而言,我需要价值我的变量要向下舍入,而不仅仅是这样显示。

round(2.357, 2)  # -> 2.36

我在这里找到了答案:How do I round a floating point number up to a certain decimal place?

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

【讨论】:

  • “值四舍五入到最接近的 10 的乘方减去 ndigits 的倍数;” docs.python.org/3/library/functions.html#round 所以不,回合并不总是四舍五入,例如round(2.354, 2) # -> 2.35
  • @PeteKirkham 你是对的,我编辑了我的答案以使其更有意义和准确。
  • 那么,你应该用负值检查你的解决方案...... math.floor(0.5357706*100)/100 -> 0.53 math.floor(-0.5357706*100)/100 -> -0.54
  • -0.54 是向下舍入 -0.5357706 的正确答案,因为它是负数,-0.54 < -0.53
  • 我会使用 10**d 而不是 int('1' + ('0' * d))
【解决方案4】:

如果只想打印四舍五入的结果,可以使用自 Python 3.6 以来引入的 f-strings。语法与str.format()format string syntax 相同,除了您在文字字符串前面放置一个f,并将变量直接放在字符串中的大括号内。

.2f表示四舍五入到小数点后两位:

number = 3.1415926
print(f"The number rounded to two decimal places is {number:.2f}")

输出:

The number rounded to two decimal places is 3.14

【讨论】:

  • 这会将 39.555 舍入为 39.55,如果您期望舍入为 39.56,则结果不正确
  • 如果有人没有将 f 放在 .2 之后,14.426599999999999 之类的数字将四舍五入为 1.4e+01。至于 Python 3.8.6
【解决方案5】:

您可以使用圆形功能。

round(80.23456, 3)

会给你一个答案 80.234

在你的情况下,使用

answer = str(round(answer, 2))

【讨论】:

  • 这应该是公认的答案。如此简单,又如此直接。
【解决方案6】:

如果你需要避免浮点数问题关于会计的舍入数字,您可以使用 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

如果您通过合法舍入管理资金,则应该使用它。

【讨论】:

  • 如果最后一位数字是 0,这将不起作用。例如,数字 39.90 将四舍五入为 39.9
  • 此方法为您提供十进制值而不是字符串。如果你想要一个你想要的格式的字符串,你应该使用@jackz314
  • 如果在 pi 上运行,请使用 pi 版本:apt install python3-numpy
  • 这是行不通的。 np.round(2.665, 2)返回2.66,而round(2.665, 2)返回2.67。这是我的解决方案。 stackoverflow.com/a/53329223/6069907
  • @SamuelDauzon 当然,我在本地试过了。我在 python 3.7(win10) 和 numpy 1.19.3 上得到了结果。
【解决方案7】:

你想四舍五入你的答案。

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&gt;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!
"))
    except ValueError:
        print "
Your 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 "
Your Celsius value is " + answer + " C.
"

main()

...应该给你你期望的结果。

您也可以使用 decimal 库来完成此操作,但我建议的包装器更简单,在某些情况下可能更受欢迎。


编辑:感谢 Blckknght 指出 5 边缘案例仅针对某些值 here 出现。

【讨论】:

  • 这不适用于负数,例如 -4.625 的计算结果为 -4.62。你能修改它以适用于负数吗?
【解决方案8】:
float(str(round(answer, 2)))
float(str(round(0.0556781255, 2)))

【讨论】:

    【解决方案9】:

    只需使用带有 %.2f 的格式,它可以让您四舍五入到 2 位小数。

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

    【讨论】:

      【解决方案10】:

      您可以使用圆形的最多 2 位小数的运算符

      num = round(343.5544, 2)
      print(num) // output is 343.55
      

      【讨论】:

        【解决方案11】:

        如果您不仅需要舍入结果,还需要用舍入结果进行数学运算,那么您可以使用decimal.Decimalhttps://docs.python.org/2/library/decimal.html

        from decimal import Decimal, ROUND_DOWN
        
        Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
        Decimal('7.32') 
        

        【讨论】:

          【解决方案12】:
          from decimal import Decimal, ROUND_HALF_UP
          
          # Here are all your options for rounding:
          # This one offers the most out of the box control
          # ROUND_05UP       ROUND_DOWN       ROUND_HALF_DOWN  ROUND_HALF_UP
          # ROUND_CEILING    ROUND_FLOOR      ROUND_HALF_EVEN  ROUND_UP
          
          our_value = Decimal(16.0/7)
          output = Decimal(our_value.quantize(Decimal('.01'), 
          rounding=ROUND_HALF_UP))
          print output
          

          【讨论】:

          • 这应该是公认的答案
          • decimal 不是内置函数,所以它真的不应该是公认的答案。
          • 对于传统的舍入,它不应该是公认的答案。
          • 另外,请始终显示输出...
          【解决方案13】:

          可以使用python的字符串格式化操作符“%”。 “%.2f”表示小数点后2位。

          def typeHere():
              try:
                  Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!
          "))
              except ValueError:
                  print "
          Your 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 "
          Your Celsius value is %.2f C.
          " % answer
          
          def main():
              printC(formeln(typeHere()))
          
          main()
          

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

          【讨论】:

            【解决方案14】:

            为了避免 round() 的意外价值,这是我的做法:

            Round = lambda x, n: eval('"%.'+str(int(n))+'f" % '+repr(int(x)+round(float('.'+str(float(x)).split('.')[1]),n)))
            
            print(Round(2, 2))       # 2.00
            print(Round(2.675, 2))   # 2.68
            

            【讨论】:

            • 不适用于 0.625。
            • 请解释您要解决的问题(什么是奇怪) 以及你的 lambda 做什么。
            【解决方案15】:

            这是我使用的示例:

            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)
            

            【讨论】:

              【解决方案16】:
              round(12.3956 - 0.005, 2)  # minus 0.005, then round.
              

              答案来自:https://stackoverflow.com/a/29651462/8025086

              【讨论】:

                【解决方案17】:

                迄今为止我找到的最简单的解决方案,不知道为什么人们不使用它。

                # Make sure the number is a float
                a = 2324.55555
                # Round it according to your needs
                # dPoints is the decimals after the point
                dPoints = 2
                # this will round the float to 2 digits
                a = a.__round__(dPoints)
                if len(str(a).split(".")[1]) < dPoints:
                    # But it will only keep one 0 if there is nothing,
                    # So we add the extra 0s we need
                    print(str(a)+("0"*(dPoints-1)))
                else:
                    print(a)
                

                【讨论】:

                  【解决方案18】:

                  因为你想要十进制数的答案所以你不需要打字回答变量到 printF() 函数中的字符串。

                  然后使用printf-style String Formatting

                  【讨论】:

                    【解决方案19】:

                    不知道为什么,但是 '{:0.2f}'.format(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
                    

                    【讨论】:

                    • 这是截断,而不是舍入。
                    • {:0.2f} 正确舍入了值。您的解决方案不是四舍五入。
                    【解决方案20】:

                    截断为 2 位数字:

                    somefloat = 2.23134133
                    truncated = int( somefloat * 100 ) / 100  # 2.23
                    

                    【讨论】:

                      【解决方案21】:

                      简单例子

                      账单 = 10.24 打印(圆(10.241))

                      【讨论】:

                      • 嗨@Savana Rohit,这个答案与这里的其他答案重复。感谢您的贡献!你的答案没有错,但其他人已经提供了这个答案。我建议删除这个答案。
                      猜你喜欢
                      • 2017-05-06
                      • 1970-01-01
                      • 2014-06-28
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-07-26
                      相关资源
                      最近更新 更多