1

I am using IronPython 2.7 integrated into Rhinoceros 5 application. I am having a strange int() function result:

import math

angle = 45.0
tangent = math.tan(math.radians(angle))
n = 12*tangent
print "angle: ", angle
print "tangent: ", tangent
print "n: ", n
print "int(n): ", int(n)

Results in:

angle:  45.0
tangent:  1.0
n:  12.0
int(n):  11

So as written above, the int() function returns 11 not 12. I know there are some floating point number issues, but this should not be related with integers? Does anyone know why is this happening?

Thank you for the reply.

EDIT: I added the code, on how I got the "12.0"

marco
  • 899
  • 5
  • 13
  • 21

2 Answers2

4

You got 11.9999999999999982 !


If you add the following line to your code, you'll get an amazing result

print "%.16f" % n

Output

11.9999999999999982

How to solve


You may want to try this:

from decimal import Decimal

k=Decimal(12.0)
print int(k) #prints 12

This will convert 12.0 (a float) to a Decimal value. This approach can solve some issues related to floats.

Why it happened


You could read this and see that, for example, 2.675 can be represented as 2.67499999999999982236431605997495353221893310546875 because of some limitations.

In your case you've got a number that's close to 12. That's why int rounded it to 11. For example:

>>> int(11.9999999999)==11
True
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • 1
    I didn't downvote, but you didn't answer any of the question – knitti May 19 '15 at 11:23
  • 3
    under no circumstances should `int(12.0)` become `11` – Padraic Cunningham May 19 '15 at 11:25
  • Your edits still don't answer the question. The OP is not experiencing floating point errors, the issue is `int(12.0)` becomes `11`. Also what OS would represent 12 as 11.999999? – Padraic Cunningham May 19 '15 at 11:30
  • @PadraicCunningham, I've edited my answer so it could explain it better – ForceBru May 19 '15 at 11:32
  • @ForceBru, it is still not answering the question. Where are you addressing rhino or ironpython's role in all this? `print(int(12.0))` under *no* circumstances should output `11` – Padraic Cunningham May 19 '15 at 11:33
  • @ForceBru: your "Why it happened"-section is speculation, and not _that_ convincing. There's no point in representing 12.0 as 11.9999999 – knitti May 19 '15 at 11:34
  • @knitti, but it may be, as you can see from the code in my answer – ForceBru May 19 '15 at 11:35
  • 1
    @ForceBru: No, you've shown that `int(11.99999999)` will give `11` not that `12.0` could be represented as `11.99999999` – SiHa May 19 '15 at 11:38
  • 1
    then it isn't an answer but a speculation. What part of an OS' representation of a number is used by python? -> This is the part where the bug is. And relates in this specific case most probably to the way python has been linked to a bugged library while being embedded into the application – knitti May 19 '15 at 11:38
  • @PadraicCunningham, @knitti, it's now clear why the OP got such results. He wasn't doing `int(12.0)`. He was performing some math before. That's why I was forced to speculate. – ForceBru May 19 '15 at 12:08
  • @ForceBru, you should not speculate and your reasoning was completely wrong. if the question needs more info ask for it, the last part of your answer should also be edited or removed. – Padraic Cunningham May 19 '15 at 12:10
  • @PadraicCunningham, you're right. Just edited it. – ForceBru May 19 '15 at 12:13
1

In your case, the error is occurring in the tan operation, and your confusion is arising because of the way that print tries to make the output more readable:

>>> math.tan(math.radians(angle))
0.9999999999999999
>>> print(math.tan(math.radians(angle)))
1.0

The easiest solution is to use round instead of int:

import math

angle = 45.0
tangent = math.tan(math.radians(angle))
n = 12*tangent
print "angle: ", angle
print "tangent: ", tangent
print "n: ", n
print "round(n,0): ", round(n,0)

Yields:

angle:  45.0
tangent:  1.0
n:  12.0
round(n,0):  12.0

As ForceBru mentioned, there is a Decimal module to help with floating-point operations, but I've found to be quite cumbersome, and rounding at the end of the calculation is normally sufficient.

SiHa
  • 7,830
  • 13
  • 34
  • 43