7

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'
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
grokus
  • 18,046
  • 9
  • 29
  • 35

4 Answers4

9

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.

Daniel G
  • 67,224
  • 7
  • 42
  • 42
6

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)

Jimmy
  • 89,068
  • 17
  • 119
  • 137
3

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.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
2

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

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395