0

There is similar question: Checking whether a variable is an integer or not, but I see no answer to my question.

I mean, I was fighting with big numbers recently, so friend of mine suggested me to install Python. I opened it today, so that I can compute big numbers and have good precision, but... how to use this precision? I mean, if I do something like pow(31,123) it works fine, but if I want to check if number is integer, I get:

>>> (4.00000000000001).is_integer()
False
>>> (4.000000000000001).is_integer()
False
>>> (4.0000000000000001).is_integer()
True
>>> (4.00000000000000001).is_integer()
True

I wanted to write simple loop to find some solutions of diophantine-equation, where I need to take square root from the very big number and check if it is integer number, but now I am in pinch. Can someone help me or give me an advice how to achieve better precision?

Example:

For example: $ 2x^2 = 1 + y^31 $, where x,y are integer numbers. My idea is to make loop, where I increment y (starting from 1), add 1, divide by 2, take square root, and then it must be integer to satisfy the equation. This is why I need it.

Community
  • 1
  • 1
Kusavil
  • 294
  • 6
  • 15
  • integers in Python have unlimited precision. But `float` numbers are usual IEEE-754 floating point numbers. See [Floating Point Arithmetic: Issues and Limitations](https://docs.python.org/3.5/tutorial/floatingpoint.html) – jfs Apr 01 '14 at 15:20

3 Answers3

7

4.0000000000000001 cannot be accurately represented as float:

>>> format(4.0000000000000001, '.53f')
'4.00000000000000000000000000000000000000000000000000000'

so that number is indeed an integer. You cannot hope to go beyond 15 decimal digits on most systems:

>>> sys.float_info.dig
15

See the sys.float_info structure, the dig attribute represents:

maximum number of decimal digits that can be faithfully represented in a float

Use the decimal module instead if you need more precision.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • But how to compare decimals? `compare` on site you gave me don't work, for example `>>> Decimal(4.0000000000000001).compare(Decimal(4.000000000000001))` gives `Decimal('-1')` , because first number have 15 zeros, when second one have 14 zeros. But when I increase number of zeros (before 1) in both of them, then comparing returns `Decimal('0')`, even thought the numbers are different :( – Kusavil Apr 01 '14 at 14:41
  • What is the configured precision? – Martijn Pieters Apr 01 '14 at 14:45
1

You can check if a given number is a square of an integer using the code below:

def is_square(x):
    s = int(sqrt(x) + 0.5)
    return s * s == x

Similar approach can be used for a diophantine equation. Just convert y found for a given x to int (y = int(y + 0.5)) and then check if diophantine equation is true for found given x and y

kostya
  • 9,221
  • 1
  • 29
  • 36
  • Can You advice how to make this work? I mean, do what You wrote above take into account precision I mentioned? I am trying to transform it, that it uses Decimal, but have some problems :( I don't know how to write it that it returns Decimal type. (My first time doing anything in Python ;) ) – Kusavil Apr 01 '14 at 14:28
  • Python int can be any size. Try to type in Python shell 2**1000 and you will get the correct answer with all 301 digits. – kostya Apr 01 '14 at 15:34
  • 1
    With the approach I proposed you do not need to take precision into account. Let me try to explain it better. First you calculate x based on y: x=sqrt((1+y**31)/2.0). This is an exact answer. Now you need to check if it is integer or not. Instead of asking x.is_integer() you can round it first x=int(x+0.5). You need to add 0.5 to make sure that a number like 3.99999999999999 is converted to 4. And then you just check if 2*x*x == 1 + y**31. Now both x and y are integers so no need to take precision into account. – kostya Apr 01 '14 at 15:35
  • It won't work. See that: >>> x = math.sqrt(((137**15)+1)/2); >>> x = int(x+0.5) ; >>> y = 1 + 137**15; then >>> y gives us 112410921330388974282595778471994; while >>> 2*x*x gives us: 112410921330388990371703613604552. Difference is about 10^16, so how I can use it to check if number if integer? – Kusavil Apr 01 '14 at 17:06
  • Hm, you are right. This is because math.sqrt works on floats and return a float. sqrt(137**15) is too big and a float cannot hold all digits. – kostya Apr 01 '14 at 18:19
  • 2
    Have a look at http://stackoverflow.com/questions/15390807/integer-square-root-in-python – kostya Apr 01 '14 at 18:21
  • Thank you for help kostya, now with your comments the problem is solved, so I mark it as solution. :) You can add this link to your answer if you want. – Kusavil Apr 01 '14 at 19:52
  • I downvoted because I think your answer glosses over accuracy questions that are important to the question. The link you later gave in the comments covers this, though. – Veedrac Nov 20 '14 at 06:50
1

Can you not use built in function 'type'? I ran the following:

print type(4.0000000000000000000000000000000000000000000000001)
print type(4)

and got the result:

<type 'float'>
<type 'int'>

You can then check occurrence of 'int' and 'float' in the result using find() method

haraprasadj
  • 1,059
  • 1
  • 8
  • 17
  • No, unfortunately I cannot. I want to check if `x` is integer number (not just type, but mathematically integer number), so 4.000 can be considered as integer number, but `print(type(4.0))' tells me `float` – Kusavil Apr 01 '14 at 14:26
  • 1
    My bad! Dumb answer!! – haraprasadj Apr 01 '14 at 14:52