仅在重复 python 时四舍五入到小数点后两位

Round to two decimal places only if repeating python

我想知道是否有人知道 python 中检查分数是否为循环小数的快速方法。

我有一个小函数,它接受两个数字并将它们相除。如果商是一个重复的小数,我想四舍五入到小数点后两位,如果商不重复,我想四舍五入到一个

示例:

800/600 = 1.33333333333333 等于 1.33

900/600 = 1.5 将保持为 1.5

我知道我需要对两种舍入使用这两个语句

output = "{:.2f}".format(float(num))
output = "{:,}".format(float(num))

但是我在使用 if 语句指向一个或另一个时遇到了问题。

任何人都可以提供一些见解吗?

repeating decimal

只有 10 个分数可以写成一些重复的数字 - .(0).(1)、... .(9)。因此,如果您只关心从小数点后开始的重复模式,则只需检查这些情况。

所有这些数字(而且只有它们)乘以 9 后得到一个整数。

因此,如果 (9 * numenator) % denominator == 0,您将打印 2 个数字。

您可能希望排除 .(0) 模式。为此,请测试您的分数是否实际上是整数 - numenator % denominator == 0.

另请查看 fractions 模块,以备不时之需。

当然,如果你的数字只有 float,那么关于什么是分子和分母就会有一些歧义,因为 float 实际上并不存储有理数,比如 1/3。您可以尝试使用 fractions.limit_denominator() 来选择适合您的情况。

使用 fractions 模块,它实现了精确的有理算术:

import fractions

# fractions.Fraction instances are automatically put in lowest terms.
ratio = fractions.Fraction(numerator, denominator)

然后您可以检查结果的 denominator

def is_repeating(fraction):
    denom = fraction.denominator
    while not (denom % 2):
        denom //= 2
    while not (denom % 5):
        denom //= 5
    return denom != 1

试试这个:使用蛮力。因为您只需要 2 位小数。只需除法,然后在四舍五入到小数点后 0 位和 1 位时对其进行测试,看看它在何处不再唯一。如果此时不唯一,则四舍五入到小数点后2位。

def f(x):
    if x == round(x,0):
        return '{:.0f}'.format(x)
    elif x == round(x,1):
        return '{:.1f}'.format(x)
    else:
        return round(x,2)

y = [1, 2, 3, 3/2, 1/9, 8/9, 1/11, 12/11, 10/11, 14/13, 1/3]
for item in y:
    print(f(item))

输出:

1
2
3
1.5
0.11
0.89
0.09
1.09
0.91
1.08
0.33
>>> 

只是使用正则表达式的解决方法:)

import re

result = str(800/600)
# result = str(900/600)

repeating_pair = re.escape(result.split('.')[1][:2])
check_within = result.split('.')[1][2:]

if re.match(repeating_pair, check_within):
    print("{:.2f}".format(float(result)))
else:
    print("{:.1f}".format(float(result)))

输出:

1.33

并且 900/600

1.5