-1

This is a small piece of a larger code.

c = (pow(1, 6) + pow(272, 6))**(1/6)

print(c)

It prints the output 272, but it's actually the 6th root of(272^6 + 1), the decimal point is negligible and hence it is just considered an integer.

How can I increase the precision enough to show the actual answer?

Thank You.

  • 1
    Why would you want `272.00000000000011194487853427598915003413248022443993784771831008` instead of `272`? the difference is less than 10^-12. You don't need that much accuracy. – Alex Mandelias Oct 21 '20 at 10:51
  • 1
    And what *exactly* would you consider to be the "actual answer"? – tripleee Oct 21 '20 at 10:52
  • 1
    use the [decimal](https://docs.python.org/3/library/decimal.html) module to obtain arbitrary precision – Reblochon Masque Oct 21 '20 at 10:53
  • @tripleee the one with all the decimal points as mentioned in AAAlex123 's answer. – Chezhiiyan Sabapathy Oct 21 '20 at 10:57
  • @AAAlex123 this is part of a bigger program verifying fermat's last theorem for a small test case, you can find the code here : https://codereview.stackexchange.com/questions/250950/ive-been-trying-to-verify-fermats-last-theorem-for-a-small-test-case-using-pyt without this amount of precision the check if integer function doesn't work. – Chezhiiyan Sabapathy Oct 21 '20 at 10:58
  • @AAAlex123 can you also tell me how you got that number. – Chezhiiyan Sabapathy Oct 21 '20 at 11:07
  • Because python's integers have arbitrary precision you can do the opposite. View my answer below (wip) – Alex Mandelias Oct 21 '20 at 11:08
  • @ChezhiiyanSabapathy I used WolframAlpha – Alex Mandelias Oct 21 '20 at 11:08
  • Edit: nope my idea doesn't work. I thought of comparing very large numbers instead of numbers with a very long decimal expansion but it still requires long decimal expansion so we have the same problem. Have a look at @ReblochonMasque's answer. haven't tried it myself but it looks like what you need. – Alex Mandelias Oct 21 '20 at 11:20
  • Edit 2: I *think* I have a solution, please do check it for yourself, I might have missed a detail. – Alex Mandelias Oct 21 '20 at 11:38

4 Answers4

3

Apart from other issues, verifying FLT by taking the nth root of a^n+b^n and checking that it isn't an integer is fundamentally misguided since the process of taking nth roots brings floating point error into play. It is possible that the numerical evidence that you adduce is by itself consistent with c mathematically being an integer.

For example, if root calculation could be taken at face value then

def f(c,n):
    return c == pow(c,n) ** (1/n)

should evaluate to True for all numbers c, but it doesn't. In particular f(272,6) evaluates to False. The fact that in your test case the c in question differs slightly from an integer doesn't show that mathematically it isn't an integer. See Is floating point math broken? for more details.

If you go this route, I would suggest rounding c (computed as you are currently doing) to the nearest integer and then checking if pow(c,n) == pow(a,n) + pow(b,n). This way round-off error will no longer be an issue, though the limited ability of floats to represent numbers will eventually do you in. For even larger values of a,b,n you might need to write a custom integer root function (using e.g. binary search). In this case the integer nth root of an integer x is defined to be the largest integer y which satisfies pow(y,n) <= x.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
2

You can use the decimal module from the python standard library to obtain arbitrary precision:

from decimal import Decimal, getcontext


getcontext().prec = 128   # get 128 decimals

c = (pow(1, 6) + pow(272, 6)) ** (1 / 6)
print(c)

d = (Decimal(1) + Decimal(pow(272, 6))) ** Decimal((1 / 6))
print(d)

output:

272.0
272.00000000000002730268738756987678453728427749629247405984602995282036227860028297571745987954219978888119652759507812823846641
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
1

Disclaimer: not sure if it works

Based on OP's question, this question and its code, the comments on this post:

The idea is to compare very large numbers instead of numbers with very long decimal expansion, because pythons integers are unbounded.

First compute c = a**g + b**g then s = int(c ** (1/g)).

Now, if (a, b, s) is a valid triplet of numbers, then either s**g or (s+1)**g would be equal to c because:

  • python's int function rounds down and
  • triplets are comprised of integer numbers.

This way, we avoid directly comparing numbers with long decimal expansion by comparing very large numbers, which python can do.

Here's the code, similar to the referenced website:

def proof(n, g):
    for a in range(1,n):
        for b in range(a, n):
            c = (pow(a, g) + pow(b, g))
            s = int(c ** (1/g))
            if (s**g == c):
                print(f"{a},{b},{s}")
            elif (s+1**g == c):
                print(f"{a},{b},{s+1}")

proof(1000, 6)

There is a trivial error (1, 1, 2) because of s+1**g, but other than that the code should work properly.

Please do check it yourself, I'm not very familiar with fermat's last theorem, something might have slipped by when coming up with a solution.

Alex Mandelias
  • 436
  • 5
  • 10
  • You are assuming that if c ** (1/g) is an integer then `int(c ** (1/g))` is at most 1 less than the exact answer, but this will not be true for large values of c (i.e. beyond 2 ** 53). – President James K. Polk Oct 21 '20 at 13:13
-1

You can declare float and then use round to get the nearest two decimal points. I just did this for a small pay calculation program. Something like:

'''
a = input ("Enter annual pay: ")
            h = float (a) / 2080
            x = round(h, 2)
            print ("Hourly pay is: ")
            print (x)
'''