简体   繁体   中英

Round to two decimal places only if repeating python

I was wondering if anybody knew of a quick way in python to check and see if a fraction gives a repeating decimal.

I have a small function that takes in two numbers and divides them. If the quotient is a repeating decimal I would like to round to 2 decimal places and if the quotient is not repeating I would like to round to just one

Example:

800/600 = 1.33333333333333 which would equal 1.33

900/600 = 1.5 would stay as 1.5

I know that I need to use the two statements for the two types of rounding

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

but I am having trouble with the if statement to direct to one or the other.

Can anybody help with some insight?

Use the fractions module, which implements exact rational arithmetic:

import fractions

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

You can then inspect the denominator of the result:

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

Try this: Just use brute force. Since you want only 2 decimal places. Just divide and then test it when it is rounded to 0 and 1 decimal place and see where it stops being unique. If it is not unique at this point, then round to 2 decimal places.

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

Output:

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

Just a workaround using regex :)

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

Output:

1.33

And for 900/600

1.5

repeating decimal

There are only 10 fractions that can be written as some repeated digit - .(0) , .(1) , ... .(9) . Thus, if you only care about repeating pattern starting right after decimal point, you only need to check against those cases.

All those numbers (and only them) give an integer if multiplied by 9.

Thus, if (9 * numenator) % denominator == 0 , you'll print 2 digits.

You'll probably want to exclude .(0) pattern though. To do that, test if your fraction is in fact an integer - numenator % denominator == 0 .

Also check out fractions module in case you have some wheels to reinvent.

Of course, if you only have your number as a float , there is some ambiguity about what numenator and denominator are, because float s don't actually store rational numbers like 1/3 . You can experiment with fractions 's .limit_denominator() to choose something that works for your case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM