# Problems to calculate sin

Discussion in 'Java' started by Steve70, Mar 4, 2008.

1. ### Steve70Guest

I must create a program that use trigonometry function.
I know sin(30)=0.5 but when I use Math.sin() I can't get it

Math.sin(30*Math.PI/180)=0.49999999999999994

What's the problem?

Thank you

Stefano Buscherini

Steve70, Mar 4, 2008

2. ### bugbearGuest

Steve70 wrote:
> I must create a program that use trigonometry function.
> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>
> Math.sin(30*Math.PI/180)=0.49999999999999994

That *is* 0.5, at least to rather good tolerance.

BugBear

bugbear, Mar 4, 2008

3. ### SannyGuest

On Mar 4, 3:40 pm, Steve70 <> wrote:
> I must create a program that use trigonometry function.
> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>
> Math.sin(30*Math.PI/180)=0.49999999999999994
>
> What's the problem?
>
> Thank you
>
> Stefano Buscherini

Math.sin uses Log tables to calculate value of Sin So they are
approximate to 0.0000000000001 Value.

You can use this value in your Calculations with error of
0.0000000000001 Thats not a big difference unless you are using it
for Rocket/ Missile Launching Program. Then you may create a function
to calculate Sin value yourself.

I suppose you know how to create Sin() using Mathematical Formulla.
Give me \$15 and I will give you the Formula.

Bye
Sanny

Sanny, Mar 4, 2008
4. ### Alex MizrahiGuest

S> I must create a program that use trigonometry function.
S> I know sin(30)=0.5 but when I use Math.sin() I can't get it

S> Math.sin(30*Math.PI/180)=0.49999999999999994

S> What's the problem?

you're using floating point numbers. their precision is quite limited, and
they cannot represent all numbers exactly. (it's not possible with fixed
amount of bits).
so, you should not depend on exact results. use rounding when doing output.
expect some degree of error when doing comparison.

using floating point numbers correctly (so you have minimal errors) might be
quite complex thing. for introduction, read
http://en.wikipedia.org/wiki/Floating_point

Alex Mizrahi, Mar 4, 2008
5. ### Roedy GreenGuest

On Tue, 4 Mar 2008 02:40:23 -0800 (PST), Steve70 <>
wrote, quoted or indirectly quoted someone who said :

>I must create a program that use trigonometry function.
>I know sin(30)=0.5 but when I use Math.sin() I can't get it
>
>Math.sin(30*Math.PI/180)=0.49999999999999994

see http://mindprod.com/jgloss/floatingpoint.html
http://mindprod.com/jgloss/trigonometry.html

If you asked a carpenter for a table .5 meters long and it was
0.49999999999999994, how would you notice?
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green, Mar 4, 2008
6. ### LewGuest

Sanny wrote:
> I suppose you know how to create Sin() using Mathematical Formulla.
> Give me \$15 and I will give you the Formula.

Come on, Sanny, do you really think anyone is going to give you cash for that
kind of thing?

"sin", lower-case "m" in "mathematical", "formula" is spelled with one "l"
and, in that context, lower-case "f". No charge for the information.

Are you this careful with the expression of your formulas, too?

--
Lew

Lew, Mar 4, 2008
7. ### Guest

On Mar 4, 5:40 am, Steve70 <> wrote:
> I must create a program that use trigonometry function.
> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>
> Math.sin(30*Math.PI/180)=0.49999999999999994
>
> What's the problem?
>
> Thank you
>
> Stefano Buscherini

A few of the other posters have commented that you need to understand
the limits of floating point arithmetic. Note that there are at least
three ways that comes into play in this problem.

Mathematically we know
sin(pi/6) = 1/2
exactly. However Math.PI is an approximation of the value of PI so
30*Math.PI/180 is an approximation of pi/6. So when we take the sine
we are taking the sine of a number that's a little different from the
number we really wanted. That's one source of error. You can see
this most easily by looking at the value
of
Math.sin(Math.PI)
It is not 0 but a value of about 10^-16. This is not an error in the
computation of the sine, it represents the difference between Java's
approximation to pi and the true value. This source of error is
sometimes a little surprising to users.

The second source of error is in the arithmetic within the
parentheses. Anytime you operate on floating point numbers, and
especially if you are dividing, you are likely to get an answer that
is not exact. For division this is easy to see. You cannot write
10./3 in any finite decimal representation. While a computer users
binary rather than decimal, the same issue arises. If we combine this
with the first error it's possible that there is a number that Java
could represent that is closer to the value pi/6 than the value you
will actually get using 60*Math.PI/180.

The last source is in the computation of the sine itself. Java
permits (but does not require except in strictmath) mathematical
functions to have very small errors in the calculations. If the
correct answer is x, the result of the computation can be either x, or
the smallest number the computer can distinguish from x that is larger
than x, or the largest number the computer can distinguish from x that
is smaller than x. In practice this means that the answer is within
about 10^-16 x of the true value.

Regards,
Tom McGlynn

, Mar 4, 2008
8. ### Patricia ShanahanGuest

Sanny wrote:
> On Mar 4, 3:40 pm, Steve70 <> wrote:
>> I must create a program that use trigonometry function.
>> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>>
>> Math.sin(30*Math.PI/180)=0.49999999999999994
>>
>> What's the problem?
>>
>> Thank you
>>
>> Stefano Buscherini

>
> Math.sin uses Log tables to calculate value of Sin So they are
> approximate to 0.0000000000001 Value.

I'm curious. Why log tables?

I don't know how Math.sin is implemented, and don't even assume it is
implemented the same way in all JVMs, but if I had to guess I would have
expected some sort of truncated Taylor series.

Patricia

Patricia Shanahan, Mar 4, 2008
9. ### SannyGuest

On Mar 4, 6:29 pm, Patricia Shanahan <> wrote:
> Sanny wrote:
> > On Mar 4, 3:40 pm, Steve70 <> wrote:
> >> I must create a program that use trigonometry function.
> >> I know sin(30)=0.5 but when I use Math.sin() I can't get it

>
> >> Math.sin(30*Math.PI/180)=0.49999999999999994

>
> >> What's the problem?

>
> >> Thank you

>
> >> Stefano Buscherini

>
> > Math.sin uses Log tables to calculate value of Sin So they are
> > approximate to 0.0000000000001 Value.

>
> I'm curious. Why log tables?
>
> I don't know how Math.sin is implemented, and don't even assume it is
> implemented the same way in all JVMs, but if I had to guess I would have
> expected some sort of truncated Taylor series.
>
> Patricia

Using Tables are faster than using a formula to compute a value.

By log table I just mean a Table for Sine. Log tables are more
familiar than Log Tables.

Bye
Sanny

Sanny, Mar 4, 2008
10. ### bugbearGuest

Sanny wrote:
> On Mar 4, 6:29 pm, Patricia Shanahan <> wrote:
>> Sanny wrote:
>>> On Mar 4, 3:40 pm, Steve70 <> wrote:
>>>> I must create a program that use trigonometry function.
>>>> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>>>> Math.sin(30*Math.PI/180)=0.49999999999999994
>>>> What's the problem?
>>>> Thank you
>>>> Stefano Buscherini
>>> Math.sin uses Log tables to calculate value of Sin So they are
>>> approximate to 0.0000000000001 Value.

>> I'm curious. Why log tables?
>>
>> I don't know how Math.sin is implemented, and don't even assume it is
>> implemented the same way in all JVMs, but if I had to guess I would have
>> expected some sort of truncated Taylor series.
>>
>> Patricia

>
> Using Tables are faster than using a formula to compute a value.
>
> By log table I just mean a Table for Sine.

(chuckle)

BugBear

bugbear, Mar 4, 2008
11. ### Patricia ShanahanGuest

Sanny wrote:
> On Mar 4, 6:29 pm, Patricia Shanahan <> wrote:
>> Sanny wrote:
>>> On Mar 4, 3:40 pm, Steve70 <> wrote:
>>>> I must create a program that use trigonometry function.
>>>> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>>>> Math.sin(30*Math.PI/180)=0.49999999999999994
>>>> What's the problem?
>>>> Thank you
>>>> Stefano Buscherini
>>> Math.sin uses Log tables to calculate value of Sin So they are
>>> approximate to 0.0000000000001 Value.

>> I'm curious. Why log tables?
>>
>> I don't know how Math.sin is implemented, and don't even assume it is
>> implemented the same way in all JVMs, but if I had to guess I would have
>> expected some sort of truncated Taylor series.
>>
>> Patricia

>
> Using Tables are faster than using a formula to compute a value.

Depends on many things, including the size of the tables. Remember that
one can do quite a lot of simple constant loading and floating point
arithmetic for the cost of one cache miss. Given the max 1 ulp error
requirement for Math.sin, I would expect a polynomial approximation to
be faster than a sufficiently precise table look-up.

> By log table I just mean a Table for Sine. Log tables are more
> familiar than Log Tables.

I assume you mean something like "Log tables are more familiar than sine
tables." However, my bachelor's degree was in mathematics. I am familiar
with sine tables, series-based approximations to sine, and have read a
little bit about cordic methods.

Do you actually know how Math.sin is implemented, or are you just saying
how you think you would implement it?

Patricia

Patricia Shanahan, Mar 4, 2008
12. ### Guest

On Mar 4, 9:05 am, Sanny <> wrote:
> On Mar 4, 6:29 pm, Patricia Shanahan <> wrote:
>
>
>
> > Sanny wrote:
> > > On Mar 4, 3:40 pm, Steve70 <> wrote:
> > >> I must create a program that use trigonometry function.
> > >> I know sin(30)=0.5 but when I use Math.sin() I can't get it

>
> > >> Math.sin(30*Math.PI/180)=0.49999999999999994

>
> > >> What's the problem?

>
> > >> Thank you

>
> > >> Stefano Buscherini

>
> > > Math.sin uses Log tables to calculate value of Sin So they are
> > > approximate to 0.0000000000001 Value.

>
> > I'm curious. Why log tables?

>
> > I don't know how Math.sin is implemented, and don't even assume it is
> > implemented the same way in all JVMs, but if I had to guess I would have
> > expected some sort of truncated Taylor series.

>
> > Patricia

>
> Using Tables are faster than using a formula to compute a value.
>
> By log table I just mean a Table for Sine. Log tables are more
> familiar than Log Tables.
>
> Bye
> Sanny

Looking at the flibdm libraries, whose algorithms are used in Sun's
JVM's, and which define the results that must be given when strictmath
is specified, the sine function consists of a range reduction such
that only the range 0 to pi/4 need be considered, followed by a
polynomial expansion to 13th order. I didn't check to see if this is
simply the Taylor expansion as Patricia suggested. It's possible that
some slight modification has better error properties. Since only odd
terms need be considered this takes relatively few operations ~ 7
additions and multiplications. It's small enough that the overhead of
the function call is probably a non-trivial fraction of the total
cost.

Table lookup and interpolation might be faster, but I wouldn't bet on
it, e.g., finding the integer index into the table given the real
input value probably soaks up a few cycles. Note that table lookup
would still have to do a range reduction first if the table were to be
any feasible size.

Regards,
Tom McGlynn

, Mar 4, 2008
13. ### Patricia ShanahanGuest

wrote:
> On Mar 4, 9:05 am, Sanny <> wrote:
>> On Mar 4, 6:29 pm, Patricia Shanahan <> wrote:
>>
>>
>>
>>> Sanny wrote:
>>>> On Mar 4, 3:40 pm, Steve70 <> wrote:
>>>>> I must create a program that use trigonometry function.
>>>>> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>>>>> Math.sin(30*Math.PI/180)=0.49999999999999994
>>>>> What's the problem?
>>>>> Thank you
>>>>> Stefano Buscherini
>>>> Math.sin uses Log tables to calculate value of Sin So they are
>>>> approximate to 0.0000000000001 Value.
>>> I'm curious. Why log tables?
>>> I don't know how Math.sin is implemented, and don't even assume it is
>>> implemented the same way in all JVMs, but if I had to guess I would have
>>> expected some sort of truncated Taylor series.
>>> Patricia

>> Using Tables are faster than using a formula to compute a value.
>>
>> By log table I just mean a Table for Sine. Log tables are more
>> familiar than Log Tables.
>>
>> Bye
>> Sanny

>
> Looking at the flibdm libraries, whose algorithms are used in Sun's
> JVM's, and which define the results that must be given when strictmath
> is specified, the sine function consists of a range reduction such
> that only the range 0 to pi/4 need be considered, followed by a
> polynomial expansion to 13th order. I didn't check to see if this is
> simply the Taylor expansion as Patricia suggested. It's possible that
> some slight modification has better error properties. Since only odd
> terms need be considered this takes relatively few operations ~ 7
> additions and multiplications. It's small enough that the overhead of
> the function call is probably a non-trivial fraction of the total
> cost.

That's about what I would have guessed. Thanks for the information.

Patricia

Patricia Shanahan, Mar 4, 2008
14. ### bugbearGuest

Patricia Shanahan wrote:
>>
>> Using Tables are faster than using a formula to compute a value.

>
> Depends on many things, including the size of the tables. Remember that
> one can do quite a lot of simple constant loading and floating point
> arithmetic for the cost of one cache miss.

I remember the shock when I first encountered this; in the days
of the 68000 - 68020 a look up table was almost
always a clear win, and I regarded (naively) lookup
tables as an "obvious" optimisation.

Then I started coding on Sun/SPARC...

I also used to think that avoiding floating point arithmetic
AT ALL COSTS was a correct speed strategy. Also naive.

BugBear

bugbear, Mar 4, 2008
15. ### Mark SpaceGuest

Steve70 wrote:
> I must create a program that use trigonometry function.
> I know sin(30)=0.5 but when I use Math.sin() I can't get it
>
> Math.sin(30*Math.PI/180)=0.49999999999999994
>
> What's the problem?
>
> Thank you
>
> Stefano Buscherini

Given the information below, you can calculate the error bounds on sine by:

|x|^15 / 15!

Using pi/4 = 0.75397 I get an error bounds of 2.04 x 10^-14, so you can
truncate/round all sines at 13 digits after the decimal point and get a
reasonable result. Note that issues with floats might still pop up, I'd
recommend doubles to be safe, unless you have a specific reason to use
floats.

Mark Space, Mar 4, 2008
16. ### Mark ThorntonGuest

wrote:
> Table lookup and interpolation might be faster, but I wouldn't bet on
> it, e.g., finding the integer index into the table given the real
> input value probably soaks up a few cycles. Note that table lookup
> would still have to do a range reduction first if the table were to be
> any feasible size.

Even with range reduction and say cubic interpolation you would still
need an enormous table to give the required accuracy. The interpolation
would cost almost as much as the series evaluation. Tables are more
common when the accuracy requirement is low and the processor has a low
performance FPU (or no hardware floating point at all).

Mark Thornton

Mark Thornton, Mar 4, 2008
17. ### Guest

On Mar 4, 3:10 pm, Mark Thornton <> wrote:
> wrote:
> > Table lookup and interpolation might be faster, but I wouldn't bet on
> > it, e.g., finding the integer index into the table given the real
> > input value probably soaks up a few cycles. Note that table lookup
> > would still have to do a range reduction first if the table were to be
> > any feasible size.

>
> Even with range reduction and say cubic interpolation you would still
> need an enormous table to give the required accuracy. The interpolation
> would cost almost as much as the series evaluation. Tables are more
> common when the accuracy requirement is low and the processor has a low
> performance FPU (or no hardware floating point at all).
>
> Mark Thornton

With cubic interpolation, I'd anticipate errors of order the fourth
power of the step size, which suggests about 10,000 interpolation
intervals would be needed to get errors of order 10^-16 (for the range
0 - pi/4). We need smaller errors for smaller values, but the
increasing linearity of sin(x) for small x probably takes care of
that. 10,000 is big enough that I'd want strong evidence that the
table approach was desirable, but not enough to preclude a table
driven approach based only upon the size of the table -- seems like it
should fit into typical cache.

However, I make no claims to understand how modern CPUs operate with
their dizzying hierarchy of caches. It may well be that this
simplistic analysis is inappropriate.

Regards,
Tom McGlynn

, Mar 4, 2008
18. ### Roedy GreenGuest

On Tue, 4 Mar 2008 05:29:03 -0800 (PST),
wrote, quoted or indirectly quoted someone who said :

>The last source is in the computation of the sine itself.

sines are computed by polynomial approximations. It is amazing they
are as accurate as they are with the low order polynomials they use.
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green, Mar 5, 2008
19. ### Roedy GreenGuest

On Tue, 4 Mar 2008 05:29:03 -0800 (PST),
wrote, quoted or indirectly quoted someone who said :

> Java
>permits (but does not require except in strictmath) mathematical
>functions to have very small errors in the calculations.

the Intel FP instruction set has a sine-computing instruction. It
works inside with polynomial approximations. Any error is Intel's
doing.

I suppose in some future chip it will have special in-parallel checks
for 45 degrees, 90 degrees, 0 degrees, 30 degrees to get as perfect as
possible results.
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green, Mar 5, 2008
20. ### Patricia ShanahanGuest

wrote:
....
> With cubic interpolation, I'd anticipate errors of order the fourth
> power of the step size, which suggests about 10,000 interpolation
> intervals would be needed to get errors of order 10^-16 (for the range
> 0 - pi/4). We need smaller errors for smaller values, but the
> increasing linearity of sin(x) for small x probably takes care of
> that. 10,000 is big enough that I'd want strong evidence that the
> table approach was desirable, but not enough to preclude a table
> driven approach based only upon the size of the table -- seems like it
> should fit into typical cache.

How many bytes per interval?

Patricia

Patricia Shanahan, Mar 5, 2008

## Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.