2013-12-20 29 views
0

好的,我的任务是生成一个数组,用正常频率生成一个正弦波。 这是我的正弦函数:Java Math.sin()无法按预期工作

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

j是数组索引和samplesPerSecond等于44100

现在10万个值的数组返回的第33 000 1.571509 ... E-14 0.0对于未来的33,000和3.143018 ... E-14。

我试过System.out.println(Math.sin(Math.PI));,它不返回0,但它返回1.224646 ... E-16

这是我的第一个Java任务,所以我会在这里可以俯瞰东西真的很明显,但我真的很困惑。

+0

什么是J和samplesPerSecond的类型? – AbhinavRanjan

+0

请注意'1.2246467991473532E-16'非常接近'0'。 'Math.sin(Math.PI))'只受'double'精度的限制。 –

+0

j和samplesPerSecond是整数。一个类型转换帮助我。 – Marv

回答

4

尝试更改为此:

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

看看它工作得更好。

我怀疑你有整数除法的问题。

在Java 2/5 = 0,你知道,而1.0 * 2/5
是你通常期望的(0.4)。

+0

是的。谢谢一堆。我们过去使用C,所以这是你想习惯Java的东西。 – Marv

+2

@Marv在C中不一样吗? ;)http://stackoverflow.com/questions/3602827/what-is-the-behavior-of-integer-division-in-c –

+0

其实......是的。没关系 。_。 – Marv

2

很可能你正在处理整数除法。所以如果分子小于分母,它将舍入为零。尝试转换/铸造j或samplesPerSecond浮动或双。

1

j是阵列索引和samplesPerSecond等于44100

作为一个数组索引,我假定jint类型。这是你的主要问题,因为你正在执行整数除法,它将结果截断为整数。无论是投jdouble,或者将之前通过双乘以:

((double)j/samplesPerSecond) 
(1.0 * j/samplesPerSecond)