Why is python giving large errors when dividing the results of sin()
Question: I was trying to find the values for the first ten integer inputs of n for an
equation I found: `x = sin(2π / n) / sin(π / n)`. The output I got from the
code I wrote to find them was quite surprising:

    
    
    >>> for i in range(1, 11):
            print math.sin(2 * math.pi / i) / math.sin(math.pi / i)
    
    -2.0
    1.22464679915e-16
    1.0
    1.41421356237
    1.61803398875
    1.73205080757
    1.8019377358
    1.84775906502
    1.87938524157
    1.90211303259
    

I realise that there will be rounding errors, and as such the following
results don't surprise me at all:

    
    
    >>> math.sin(2 * math.pi)
    -2.4492935982947064e-16
    >>> math.sin(math.pi)
    1.2246467991473532e-16
    

The question is, how did the first result end up with -2.0, I might expect it
to return something close to zero or an error / nan?

If you are interested in knowing, this equation should give the length (x) of
a line that stretches between one point and another point 2 points away in a
shape with n equal sides of 1 and all equal angles (the length of the smallest
diagonal of an isogon with side length 1).


Answer: For the second result, the impact is quite small in absolute terms:
1.22464679915e-16 is a very small number and very close to zero, about
0.00000000000000012246

If you simply want to avoid that small error having a large impact in how your
results are displayed, use a formatting string, e.g:

    
    
    for i in range(1, 11):
        print "{0:.10f}".format(math.sin(2 * math.pi / i) / math.sin(math.pi / i))
    

output:

    
    
    -2.0000000000
    0.0000000000
    1.0000000000
    1.4142135624
    1.6180339887
    1.7320508076
    1.8019377358
    1.8477590650
    1.8793852416
    1.9021130326
    

> how did the first result end up with -2.0, I might expect it to return
> something close to zero or an error / nan?

The first result is when i is 1, so it simplifies to:

    
    
    math.sin(2 * math.pi) / math.sin(math.pi)
    

Due to floating point errors, `math.sin(2 * math.pi)` evaluates to
`-2.44921270764e-16`, while `math.sin(math.pi)` evaluates to
`1.22460635382e-16`.

A floating point division of `-2.44921270764e-16 / 1.22460635382e-16` gives
`-2.0`, so that's the final output.

In the absence of floating point errors, both `math.sin(2 * math.pi)` and
`math.sin(math.pi)` should have evaluated to zero, but it just so happened by
the combined quirks of the floating point implementation and Python sin
function implementation that the floating point error of the first was twice
that of the second, and negative, so dividing them gave -2.

The floating point error in the internal representation of `math.pi * 2` is
twice that of `math.pi` because when you double a value with an error margin
the error margin also doubles, and it is not possible to represent pi as a
floating point number without some error. Speculation: that error propagates
through the sin calculation, and a negative is introduced because of something
in the sin calculation related to the fact that the sin function in the range
of pi to 2 pi is the negative of the function in the range of 0 to pi.

If you want to round extremely small values to zero, you can use
[numpy.around](http://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html#numpy.around)
to round to a given number of decimals, e.g:

    
    
    import numpy
    for i in range(1, 11):
        print numpy.around(numpy.sin(2 * numpy.pi / i), 15) / numpy.around(numpy.sin(numpy.pi / i), 15)
    

This produces a nan for the first result.

