2

I am trying to write a program in python 2.7 that will first see if a number divides the other evenly, and if it does get the result of the division.

However, I am getting some interesting results when I use large numbers.

Currently I am using:

from __future__ import division
import math
a=82348972389472433334783
b=2
if a/b==math.trunc(a/b):
    answer=a/b
    print 'True' #to quickly see if the if loop was invoked

When I run this I get:

True

But 82348972389472433334783 is clearly not even.

Any help would be appreciated.

wim
  • 338,267
  • 99
  • 616
  • 750
Dan
  • 123
  • 4
  • Won't you bee looking to check the modulus of `a` divided by 2? I'd recommend changing your `if` to `if a % 2:`. This will give you `0` if `a` is even,`1` if `a` is odd. Because what I believe you're effectively doing is comparing whether `a/b` equals `a/b` (you're dividing integers, so `trunc` has no effect, right?) – Savir Oct 25 '16 at 20:07
  • 4
    Result of the division is a floating point number. You simply asks "[is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken)" – Łukasz Rogalski Oct 25 '16 at 20:10
  • @user2357112 The result of division *is* a float, because `from __future__ import division`. – jme Oct 25 '16 at 20:13
  • @jme: oh what how did I miss that never mind – user2357112 Oct 25 '16 at 20:13
  • 2
    Compare `a//b` and `math.trunc(a/b)`. They are very different. Your machine's `double` type doesn't have enough precision to accurately store `a/b`. – chepner Oct 25 '16 at 20:17
  • @wim Oops. By the way, I laughed at the edited title. – jme Oct 25 '16 at 20:20

3 Answers3

5

That's a crazy way to do it. Just use the remainder operator.

if a % b == 0:
    # then b divides a evenly
    quotient = a // b
wim
  • 338,267
  • 99
  • 616
  • 750
  • That would let me know if it is divided evenly, but how would I know what the exact result would be? I need to know the exact division if it is evenly divisible later on in my code. – Dan Oct 25 '16 at 20:09
  • @wim my problem comes from the fact that when I do a/b with from __future__ import division it gives me the wrong answer. Would using quotient=a//b not make that mistake? – Dan Oct 25 '16 at 20:20
  • 2
    @Dan `a//b` does not produce a floating point result, so there is no error here. `quotient` is the correct result (when it is divisible) – zvone Oct 25 '16 at 20:26
  • @zvone When I do a//b in my code it still gives me a decimal not an integer. How do I fix this? – Dan Oct 25 '16 at 20:31
  • @Dan `//` produces float if it is dividing floats. `1.0//1` is `1.0`, but with integers inputs, the results is an integer (int or long): `1000000000000000//2` is `500000000000000L` – zvone Oct 25 '16 at 20:36
1

The true division implicitly converts the input to floats which don't provide the precision to store the value of a accurately. E.g. on my machine

>>> int(1E15+1)
1000000000000001
>>> int(1E16+1)
10000000000000000

hence you loose precision. A similar thing happens with your big number (compare int(float(a))-a).
Now, if you check your division, you see the result "is" actually found to be an integer

>>> (a/b).is_integer()
True

which is again not really expected beforehand.

The math.trunc function does something similar (from the docs): Return the Real value x truncated to an Integral (usually a long integer).

The duck typing nature of python allows a comparison of the long integer and float, see Checking if float is equivalent to an integer value in python and Comparing a float and an int in Python.

Community
  • 1
  • 1
Jakob
  • 19,815
  • 6
  • 75
  • 94
0

Why don't you use the modulus operator instead to check if a number can be divided evenly?

n % x == 0

Wiredo
  • 220
  • 3
  • 14