-1

This is a simple code I wrote in Python for telling if the input is odd or even. It is also probably redundant in some parts(I was just trying so that the program doesn't crash for any input).

try:
    num = input("Please,\nenter your integer to check if it's odd or even: ")
    rem = float(num) % 2
    if rem == 0:
        print("Your number", int(num), "belongs to the set of even integers!")
    elif rem == 1:
        print("Your number", int(num), "belongs to the set of odd integers!")
    else:
        print("Your number", num, "does not belong to the set of integers!")
except ValueError:
    print("Your input does not belong to the set of integers!")

Such a simple operation gives a wrong result for a 17 digit number. For example

Please,
enter your integer to check if it's odd or even: 49761934591459137
Your number 49761934591459137 belongs to the set of even integers!

Why is this happening, when python can even perform tetration(repeated exponentiation) of 2 upto 5 times(which is a 19,729 digit number)?

AMC
  • 2,642
  • 7
  • 13
  • 35
Reet Jaiswal
  • 113
  • 1
  • 2
    Because you are using `float` objects, which are fixed-size. Try to do the tetration with a `float` and you'll see you will quickly get incorrect results due to overflow. – juanpa.arrivillaga Sep 01 '20 at 18:41
  • @juanpa.arrivillaga Thanks for the tetration problem. But still how can python mess up division by 2? – Reet Jaiswal Sep 01 '20 at 18:44
  • use ```int``` instead of ```float``` – Abdeslem SMAHI Sep 01 '20 at 18:45
  • 2
    What? Are you not reading what I'm writing? **float objects are fixed size and will not accurately represent numbers of this size**. Consider, `float(49761934591459137) + 1 == float(49761934591459137)` This isn't "python messing up", this is a fundamental limitation of fixed-precision floating point formats. This is really a fundamental thing you need to grok before working with `float` objects – juanpa.arrivillaga Sep 01 '20 at 18:46
  • 2
    Why do you use ``float(num)`` for checking the condition in the first place, when you use ``int(num)`` for the output? – MisterMiyagi Sep 01 '20 at 18:49
  • Basically, `float(49761934591459137)` requires 16 digits of precision, but double-precision floating-point format only supports 15. Check out `import sys; print(sys.float_info)` – juanpa.arrivillaga Sep 01 '20 at 18:49
  • 1
    Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – MisterMiyagi Sep 01 '20 at 18:51
  • Thanks this does answer my question. – Reet Jaiswal Sep 01 '20 at 18:56

1 Answers1

2

You converted the number to float so this is what happens

number_str = 49761934591459137
print(float(number_str))
>> 4.976193459145914e+16

It gets rounded, if you convert it to integer again you get this

print(int(float(number_str)))
>> 49761934591459136

So the last digit was converted from 7 to 6. This happens because the float representation in bytes has one part for the exponent and other for the base, which means the least significant digits lose precision on bigger numbers.

You can fix your code by casting the number to integer

rem = int(num) % 2

but a smarter approach would only get the last digit and see if its divisible by 2

rem = int(num[-1]) % 2

So you can write an input of arbitrary length

Khanis Rok
  • 617
  • 6
  • 12