Python 如何将浮点数四舍五入到某个小数位?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4518641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 16:05:49  来源:igfitidea点击:

How to round a floating point number up to a certain decimal place?

pythonfloating-point

提问by hsinxh

Suppose I have 8.8333333333333339, and I want to convert it to 8.84. How can I accomplish this in Python?

假设我有8.8333333333333339,并且我想将其转换为8.84. 如何在 Python 中完成此操作?

round(8.8333333333333339, 2)gives 8.83and not 8.84. I am new to Python or programming in general.

round(8.8333333333333339, 2)8.83而不是8.84。我是 Python 或一般编程的新手。

I don't want to print it as a string, and the result will be further used. For more information on the problem, please check Tim Wilson's Python Programming Tips: Loan and payment calculator.

我不想将其打印为字符串,结果将进一步使用。有关该问题的更多信息,请查看Tim Wilson 的 Python 编程技巧:贷款和付款计算器

采纳答案by martineau

8.833333333339(or 8.833333333333334, the result of 106.00/12) properly rounded to two decimal places is 8.83. Mathematically it sounds like what you want is a ceiling function. The one in Python's mathmodule is named ceil:

8.833333333339(或8.833333333333334)的结果106.00/12正确四舍五入到小数点后两位是8.83。从数学上讲,这听起来像是您想要的天花板函数。Pythonmath模块中的一个名为ceil

import math

v = 8.8333333333333339
print(math.ceil(v*100)/100)  # -> 8.84

Respectively, the floor and ceiling functions generally map a real number to the largest previous or smallest following integer which has zero decimal places — so to use them for 2 decimal places the number is first multiplied by 102(or 100) to shift the decimal point and is then divided by it afterwards to compensate.

分别地,地板和天花板函数通常将实数映射到最大的前一个或最小的后一个整数,其中小数位为零 - 因此要将它们用于 2 个小数位,该数字首先乘以 10 2(或 100)以移动小数点点,然后除以它来补偿。

If you don't want to use the mathmodule for some reason, you can use this (minimally tested) implementation I just wrote:

如果您math出于某种原因不想使用该模块,您可以使用我刚刚写的这个(最少测试的)实现:

def ceiling(x):
    n = int(x)
    return n if n-1 < x <= n else n+1

How this applies to the linked loan and payment calculator problem

这如何适用于关联贷款和付款计算器问题

screenshot of loan calculator output

贷款计算器输出截图

From the sample output it appears that they rounded upthe monthly payment, which is what many call the effect of the ceiling function. This means that each month a little more than 112of the total amount is being paid. That made the final payment a little smaller than usual — leaving a remaining unpaid balance of only 8.76.

从样本输出看来,他们将每月付款四舍五入,这就是许多人所说的上限函数的效果。这意味着每个月支付的总金额略高于112。这使得最后的付款比平时少了一点——剩下的未付余额只有8.76.

It would have been equally valid to use normal rounding producing a monthly payment of 8.83and a slightly higher final payment of 8.87. However, in the real world people generally don't like to have their payments go up, so rounding up each payment is the common practice — it also returns the money to the lender more quickly.

使用正常四舍五入产生每月付款8.83和略高的最终付款同样有效8.87。然而,在现实世界中,人们通常不喜欢他们的付款增加,因此将每笔付款四舍五入是常见的做法 - 它还可以更快地将钱退还给贷方。

回答by orip

Use the decimalmodule: http://docs.python.org/library/decimal.html

使用decimal模块:http: //docs.python.org/library/decimal.html

??????

??????

回答by Tim Pietzcker

This is normal(and has nothing to do with Python) because 8.83 cannot be represented exactly as a binary float, just as 1/3 cannot be represented exactly in decimal (0.333333... ad infinitum).

这是正常的(与 Python 无关),因为 8.83 不能完全表示为二进制浮点数,就像 1/3 不能完全表示为十进制一样(0.333333...无限期)。

If you want to ensure absolute precision, you need the decimalmodule:

如果要确保绝对精度,则需要decimal模块:

>>> import decimal
>>> a = decimal.Decimal("8.833333333339")
>>> print(round(a,2))
8.83

回答by Andreas L?ve Selvik

If you round 8.8333333333339 to 2 decimals, the correct answer is 8.83, not 8.84. The reason you got 8.83000000001 is because 8.83 is a number that cannot be correctly reprecented in binary, and it gives you the closest one. If you want to print it without all the zeros, do as VGE says:

如果将 8.8333333333339 取整到两位小数,则正确答案是 8.83,而不是 8.84。您得到 8.83000000001 的原因是因为 8.83 是一个无法正确表示为二进制的数字,它为您提供了最接近的数字。如果你想在没有所有零的情况下打印它,按照 VGE 说的做:

print "%.2f" % 8.833333333339   #(Replace number with the variable?)

回答by Rosh Oxymoron

If you want to round, 8.84 is the incorrect answer. 8.833333333333 rounded is 8.83 not 8.84. If you want to always round up, then you can use math.ceil. Do both in a combination with string formatting, because rounding a float number itself doesn't make sense.

如果你想四舍五入,8.84 是不正确的答案。8.833333333333 四舍五入是 8.83 而不是 8.84。如果你想总是四舍五入,那么你可以使用 math.ceil。将两者与字符串格式结合使用,因为舍入浮点数本身没有意义。

"%.2f" % (math.ceil(x * 100) / 100)

回答by casevh

You want to use the decimal module but you also need to specify the rounding mode. Here's an example:

您想使用十进制模块,但您还需要指定舍入模式。下面是一个例子:

>>> import decimal
>>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_UP)
Decimal('8.34')
>>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN)
Decimal('8.33')
>>> 

回答by twohot

Just for the record. You could do it this way:

只是为了记录。你可以这样做:

def roundno(no):
    return int(no//1 + ((no%1)/0.5)//1)

There, no need for includes/imports

在那里,不需要包含/导入

回答by user2252471

A much simpler way is to simply use the round() function. Here is an example.

一个更简单的方法是简单地使用 round() 函数。这是一个例子。

total_price = float()
price_1 = 2.99
price_2 = 0.99
total_price = price_1 + price_2

If you were to print out total_price right now you would get

如果你现在打印 total_price,你会得到

3.9800000000000004

But if you enclose it in a round() function like so

但是如果你像这样将它包含在一个 round() 函数中

print(round(total_price,2))

The output equals

输出等于

3.98

The round() function works by accepting two parameters. The first is the number you want to round. The second is the number of decimal places to round to.

round() 函数通过接受两个参数来工作。第一个是您要舍入的数字。第二个是要四舍五入的小数位数。

回答by opra

Here is my solution for the round up/down problem

这是我对向上/向下舍入问题的解决方案

< .5  round down

> = .5  round up


import math

def _should_round_down(val: float):
    if val < 0:
        return ((val * -1) % 1) < 0.5
    return (val % 1) < 0.5

def _round(val: float, ndigits=0):
    if ndigits > 0:
        val *= 10 ** (ndigits - 1)
    is_positive = val > 0
    tmp_val = val
    if not is_positive:
        tmp_val *= -1
    rounded_value = math.floor(tmp_val) if _should_round_down(val) else math.ceil(tmp_val)
    if not is_positive:
        rounded_value *= -1
    if ndigits > 0:
        rounded_value /= 10 ** (ndigits - 1)
    return rounded_value

# test
# nr = 12.2548
# for digit in range(0, 4):
#     print("{} decimals : {} -> {}".format(digit, nr, _round(nr, digit)))

# output
# 0 decimals : 12.2548 -> 12
# 1 decimals : 12.2548 -> 12.0
# 2 decimals : 12.2548 -> 12.3
# 3 decimals : 12.2548 -> 12.25

回答by sai surya madhav

The easiest way to do this is by using the below function, which is built in:

最简单的方法是使用以下内置函数:

format()

For example:

例如:

format(1.242563,".2f")

The output would be:

输出将是:

1.24

Similarly:

相似地:

format(9.165654,".1f")

would give:

会给:

9.2