0

Okay, my assignment is to produce an array values a sine wave with a custom frequency. This is my sine function:

Math.sin(frequency*(j/samplesPerSecond)*Math.PI*2)

j is the array index and samplesPerSecond equals 44100.

Now for an array of 100,000 values it returns 0.0 for the first 33,000, 1.571509...E-14 for the next 33,000 and 3.143018...E-14 for the rest.

I've tried System.out.println(Math.sin(Math.PI)); and it doesn't return 0 but it returns 1.224646...E-16

This is my first java assignment so I might be overlooking something really obvious here, but I'm really confused.

Marv
  • 3,517
  • 2
  • 22
  • 47

4 Answers4

4

Try changing to this:

Math.sin(1.0 * frequency*(1.0 * j / samplesPerSecond) * Math.PI * 2)

See if it works better.

I suspect you have issue with integer division.

In Java 2/5 = 0, you know, while 1.0 * 2 / 5
is what you would expect usually ( 0.4 ).

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • Yeah. Thanks a bunch. We used to use C, so this is something you want to get used to in Java. – Marv Dec 20 '13 at 16:09
  • 2
    @Marv Isn't it the same in C? ;) http://stackoverflow.com/questions/3602827/what-is-the-behavior-of-integer-division-in-c – peter.petrov Dec 20 '13 at 16:10
2

Most probably you are dealing with integer division. So if the numerator is less than denominator it will round to zero. Try converting/casting j or samplesPerSecond to float or double.

AbhinavRanjan
  • 1,638
  • 17
  • 21
1

j is the array index and samplesPerSecond equals 44100.

As an array index, I assume j is of type int. This is your primary issue, as you're performing integer division, which truncates the result to a whole number. Either cast j to a double, or multiply it by a double before dividing:

((double)j / samplesPerSecond)
(1.0 * j / samplesPerSecond)
Brian S
  • 4,878
  • 4
  • 27
  • 46
0

I've tried System.out.println(Math.sin(Math.PI)); and it doesn't return 0 but it returns 1.224646...E-16

It has been already stated that this has to do with the finite precision of double. I use something like this in those cases:

 double result = Math.sin(2*Math.PI);
 for(double d=-1;d<=1;d=d+0.05){
        if(Math.abs(i-result) <1E-10){
            result = d;
        }
    }
 System.out.println(result); //prints 0