Question

I want to get 1/7 with better precision, but it got truncated. How can I get better precision when I convert a rational number?

>>> str(1.0/7)[:50]
'0.142857142857'
Was it helpful?

Solution

Python has a built-in library for arbitrary-precision calculations: Decimal. For example:

>>>from decimal import Decimal, getcontext
>>>getcontext().prec = 50
>>>x = Decimal(1)/Decimal(7)
>>>x
Decimal('0.14285714285714285714285714285714285714285714285714')
>>>str(x)
'0.14285714285714285714285714285714285714285714285714'

Look at the Python Decimal documentation for more details. You can change the precision to be as high as you need.

OTHER TIPS

You could multiply the numerator by a large 10^N and stick with arbitrary-precision integers.

EDIT

i mean:

> def digits(a,b,n=50): return a*10**n/b
.
> digits(1,7)
14285714285714285714285714285714285714285714285714L

Python's integers are arbitrary precision. Python's floats are never arbitrary precision. (you'd have to use Decimal, as another answer has pointed out)

Using Perl (because I can't write Python ;-):

use strict; use warnings;

use integer;

my $x = 1;
my $y = 7;

for (1 .. 50) {
    $x *= 10 if $x < $y;
    my $q = $x / $y;
    $x -= $q * $y;
    print $q;
}

print "\n";
14285714285714285714285714285714285714285714285714

As you can verify by hand, the digits repeat. Printing using "%.50f" will give you the illusion of more precision.

With gmpy:

>>> import gmpy
>>> thefraction = gmpy.mpq(1, 7)
>>> hiprecfloat = gmpy.mpf(thefraction, 256)
>>> hiprecfloat.digits(10, 50, -10, 10)
'0.14285714285714285714285714285714285714285714285714'
>>> 

You can't do it with normal floats -- they just don't have enough precision for 50 digits! I imagine there's a way to do it (in 2.6 or better) with fractions.Fraction, but I'm not familiar with any way to format it otherwise than as '1/7' (not very useful in your case!-).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top