0

I am trying to create a program that checks if an equation creates a whole number answer but the equation creates floating point numbers that won't compare to integers. When it gets to the first integer, which is supposed to be 390625 it prints it as 390625.0 and it doesn't leave the while loop when it gets to that number.

I'm new to programming so please keep it simple.

from myro import *
from math import *

def main():
    z = 3
    a = 2
    b = 2
    x = 3
    y = 3

    lim = 25

    c = (a**x + b**y)**(1.0/z)

    while int(c) != c:
        while z <= lim:
            while a <= lim:
                while b <= lim:
                    while x <= lim:
                        while y <= lim:
                            c = (a**x + b**y)**(1.0/z)
                            print a, b, c, x, y, z
                            y = y + 1

                        y = 3
                        print a, b, c, x, y, z
                        x = x + 1

                    x = 3
                    print a, b, c, x, y, z
                    b = b + 1

                b = 3
                print a, b, c, x, y, z
                a = a + 1

            a = 3
            print a, b, c, x, y, z
            z = z + 1

        print "code cycle complete. no numbers meet criteria"

    print str(a) + "^" + str(x) + " + " + str(b) + "^" + str(y) + " = " + str(c) + "^" + str(z)

main()
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Felis Vulpes
  • 33
  • 2
  • 7
  • Batman lives in a cave not a nest silly. – Felis Vulpes Jun 07 '13 at 06:42
  • Are you trying to find the first integral c which solves the equation, or any integral c? – 2rs2ts Jun 07 '13 at 23:04
  • Yesh :3 when it reaches the first number that makes int(c) and c equal it should print the statement at the end str(a) etc. – Felis Vulpes Jun 07 '13 at 23:19
  • Ok. I see @Sinoj's answer solved it for you, but, in the future, the [`break`](http://docs.python.org/2/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops) statement may help you. I am not a fan of `return`s placed anywhere except the last statement of the function. :P (In short, you would `break` if `c` was integral, then return it.) – 2rs2ts Jun 07 '13 at 23:59

5 Answers5

1

You have to be aware of the way floats are internally represented by your hardware. For example:

>>> x = 9999999.99
>>> y = 9999999.9900000002
>>> x == y
True
>>> x
9999999.9900000002
>>> y
9999999.9900000002

(this is Python 2.6, Intel CentOS-64bit; result might change depending on your architecture, but you get the idea)

That said, if your result happens to be 100.0, sure, you'll say that's a whole number. What about 100.000000000000000000001? Is that the real result of your equation, or some small deviation due to the way floats are represented in your computer's hardware?

You should read this: Floating Point Arithmetic: Issues and Limitations

And perhaps consider using the decimal package (with some performance tradeoff)

Update

If you use the decimal package you can use the remainder operator % and the is_zero() method. Example:

>>> from decimal import Decimal
>>> x = Decimal('100.00000000000001')
>>> y = Decimal('100.00000000000000')
>>> (x % 1).is_zero()
False
>>> (y % 1).is_zero()
True
E.Z.
  • 6,393
  • 11
  • 42
  • 69
1

I'm surprised by the fact that everyone jumped in to conclude that the issue is with floating point comparison. You guys should take a look at the full question/code before coming to a conclusion and rushing to answer.

Let's come back to the point. I'm not trying to explain the issues with floating point comparison. I'm not looking at the nested while loop. I'll answer considering the fact that the author needs to break the loop when the calculation results in a whole number.

Felis Vulpes, You expect the loop to break when 'c' is a whole number. But your condition "int(c) != c" is not checked as often as you think. 1. This will be checked when entering the loop. At that time the value for "c" will be 2.51984209979 2. Next checking will happen only after all the loops inside are finished. At that time, value of c will be 25.7028456664

What you will have to do is to check the value of "c" every time you recalculate it. Your code may look like this

from myro import *
from math import *

def main():
    z = 3
    a = 2
    b = 2
    x = 3
    y = 3

    lim = 25

    c = (a**x + b**y)**(1.0/z)

    #while int(c) != c:
    while z <= lim:
        while a <= lim:
            while b <= lim:
                while x <= lim:
                    while y <= lim:
                        c = (a**x + b**y)**(1.0/z)
                        print a, b, c, x, y, z
                        if int(c) == c:
                            print str(a) + "^" + str(x) + " + " + str(b) + "^" + str(y) + " = " + str(c) + "^" + str(z)
                            return
                        y = y + 1

                    y = 3
                    print a, b, c, x, y, z
                    x = x + 1

                x = 3
                print a, b, c, x, y, z
                b = b + 1

            b = 3
            print a, b, c, x, y, z
            a = a + 1

        a = 3
        print a, b, c, x, y, z
        z = z + 1

    print "code cycle complete. no numbers meet criteria"

main()
Sinoj
  • 416
  • 2
  • 5
0
abs(c - int(c)) < 0.0000001
falsetru
  • 357,413
  • 63
  • 732
  • 636
0

You need something that checks if an equation creates a whole number answer

May be you can do this:

if(c-int(c))==0:
    #code

Let x be a number. Then x = [x] + {x} ... (1), where [] is greatest integer function (floor function), and {} is fractional function

For example x = 4.5 = 4 + 0.5 implies, [4.5] = 4, {4.5} = 0.5

From (1), {x} = x - [x], which should be zero, if x is a whole number.

sinhayash
  • 2,693
  • 4
  • 19
  • 51
-1

you can just convert the float to int like this.....

ab = 1.00
ab = int(ab)
abhishekgarg
  • 1,480
  • 9
  • 14
  • Yes but if I do that I will be comparing an integer to an integer of the same number, which will always deliver the same answer. I'm trying to compare a float to an integer. – Felis Vulpes Jun 07 '13 at 06:41
  • @FelisVulpes: no, nothing is being compared here. The answer shows you how to turn a float into an integer for comparison. – Martijn Pieters Jun 07 '13 at 06:51
  • But the original code already uses `int()`, so you are asking the wrong question; the question is why `int(c) != c` isn't working for you. – Martijn Pieters Jun 07 '13 at 06:53
  • Yush :3 that is my question. Or to rephrase it: How do I make int(c) != c work? – Felis Vulpes Jun 07 '13 at 06:56