给定这种计算x的余弦的方法:
public static double myCos(double x){
double alteSumme, neueSumme, summand;
int j = 0;
neueSumme = 1.0;
summand = 1.0;
do
{
j++;
summand *= -x * x / j;
j++;
summand /= j;
alteSumme = neueSumme;
neueSumme += summand;
} while ( neueSumme != alteSumme );
return alteSumme;
}
我必须将域名从实数转换为区间 [0,PI / 2] 以获得准确的结果。
所以,我写了这个方法:
public static double transform(double x){
x = x%(2*Math.PI);
if(!(0<=x&&x<Math.PI)){
x = -(x+Math.PI);
}
if(!(0<=x&&x<Math.PI/2)){
x = -(x-2*Math.abs(x-Math.PI/2));
}
return x;
}
它应分三步完成。
将域从reals转换为[0,2PI)。
将域名从[0,2PI]转换为[0,PI)。
将域名从[0,PI)转换为[0,PI / 2]
但不知何故,它会产生错误的结果。
你帮我找错了吗?修改
public class Main {
public static double transform(double x) {
x = x % (2 * Math.PI);
if (!(0 <= x && x < Math.PI)) {
x = -(x + Math.PI);
}
if (!(0 <= x && x < Math.PI / 2)) {
x = -(x - 2 * Math.abs(x - Math.PI / 2));
}
return x;
}
public static double myCos(double x) {
x = transform(x);
double alteSumme, neueSumme, summand;
int j = 0;
neueSumme = 1.0;
summand = 1.0;
do {
j++;
summand *= -x * x / j;
j++;
summand /= j;
alteSumme = neueSumme;
neueSumme += summand;
} while (neueSumme != alteSumme);
return alteSumme;
}
public static void main(String[] args) {
int n = 0;
int k =50;
for (double y = k * Math.PI; y <= (k + 2) * Math.PI; y += Math.PI/4) {
System.out.println(n + ":" + y + ": " + myCos(y) + " " + Math.cos(y));
n++;
}
}
}
答案 0 :(得分:1)
<强>更新强>
以下是transform
仅适用于cos
的实现。
/**
* @param x any value
* @return x within [0..2PI)
public static double transform(double x) {
x = Math.abs(x); // We can do this because Cosine is symmetric around the y axis.
double y = Math.floor(x / (Math.PI * 2));
return x - y * Math.PI * 2;
}
根据要求,这是我的测试类:
package cosine;
public class Main {
public static double transform(double x) {
x = Math.abs(x);
double y = Math.floor(x / (Math.PI * 2));
return x - y * Math.PI * 2;
}
public static double myCos(double x) {
x = transform(x);
double alteSumme, neueSumme, summand;
int j = 0;
neueSumme = 1.0;
summand = 1.0;
do {
j++;
summand *= -x * x / j;
j++;
summand /= j;
alteSumme = neueSumme;
neueSumme += summand;
} while (neueSumme != alteSumme);
return alteSumme;
}
public static void main(String[] args) {
int n = 0;
for (double y = -20 * Math.PI; y < 20 * Math.PI; y += Math.PI / 3) {
double x = Math.PI / 3 + y;
double tmpa, tmpb;
System.out.println(
n + ":" + x + ": " + (tmpa = myCos(x)) + " " + (tmpb = Math.cos(x)) + " DIFF: " + (tmpa - tmpb));
n++;
}
}
}
<强>更新强>
仅通过计算余弦超过0..π:
,这是一个小小的改进public static double myCos(double x) {
// Cosine is symmetric around the Y axis: get rid of the sign.
x = Math.abs(x);
// Calculate the number of times 2*PI fits in x
double y = Math.floor(x / (Math.PI * 2));
// and subtract that many 2*PI
x -= y * Math.PI * 2;
// x is now within 0 and 2*PI.
// The PI..2PI range is the negated version of 0..PI.
double sign = 1;
if ( x > Math.PI ) {
sign = -1;
// mirror x in the line x=Math.PI:
x = - x + Math.PI; // or: Math.PI * 2 - x
}
/* cosine approximation ... */
return alteSumme * sign;
}