Java 通过sin(x)和cos(x)幂级数 编程计算其结果

124 篇文章 0 订阅
111 篇文章 0 订阅
package com.xiuye.util.algorithm.basics;

import com.xiuye.util.X;

import java.math.BigDecimal;
import java.math.BigInteger;

public class Sin {
    /**
     * y = 0.987862x - 0.155271x^3 + 0.00564312x^5
     *
     * @param c
     * @return
     */
    public static double sin1(double cn) {
        X.lg("sin1:", cn);
        double a = 0.987862;
        double b = 0.155271;
        double c = 0.00564312;


        return a * cn - b * cn * cn * cn + c * cn * cn * cn * cn * cn;
    }


    //sin(x) 幂级数
    public static double sin2(double x) {
        //把大于 -2PI 和 2PI 的值放入区间内

        int rSign = 1;
        if(x<0){
            rSign = -rSign;
            x = -x;
        }
        // >2PI
        x %= 2*Math.PI;
        // >

        X.lg("sin2:", x);
        int cnt = 0;
        double derr = 1e-15;

        long exp = 1;
        int sign = 1;
        double r = x;

        for (long n = 1; ; n++) {

            sign = -sign;//-1 or +1
            double xm = x;
            long m = 2 * n + 1;
            exp *= m * (m - 1);
            xm = Math.pow(x, m);
//            X.lg("m:",m);
//            X.lg("exp:",exp);
//            X.lg("xm:",xm);
            if (exp < 0 || xm / exp < derr) {
                break;
            }
            r += sign * xm / exp;
            cnt++;


        }
        X.lg("sin2.cnt:", cnt);
        return rSign*r;

    }

    //cos(x) 幂级数
    public static double cos2(double x) {
        //把大于 -2PI 和 2PI 的值放入区间内

        int rSign = 1;
        if(x<0){
//            rSign = -rSign;
            x = -x;
        }
        // >2PI
        x %= 2*Math.PI;
        // >

        X.lg("cos2:", x);
        int cnt = 0;
        double derr = 1e-15;

        long exp = 1;
        int sign = 1;
        double r = 1;

        for (long n = 1; ; n++) {

            sign = -sign;//-1 or +1
            double xm = x;
            long m = 2 * n;
            exp *= m * (m - 1);
            xm = Math.pow(x, m);
//            X.lg("m:",m);
//            X.lg("exp:",exp);
//            X.lg("xm:",xm);
            if (exp < 0 || xm / exp < derr) {
                break;
            }
            r += sign * xm / exp;
            cnt++;


        }
        X.lg("cos2.cnt:", cnt);
        return rSign*r;

    }




    public static void main(String[] args) {
        X.lg("PI/2", sin1(Math.PI / 2));
        X.lg("PI/6", sin1(Math.PI / 6));
        X.lg("PI/4", sin1(Math.PI / 4));
        X.lg(1 / Math.sqrt(2));
        X.lg("PI/2", sin2(Math.PI / 2));
        X.lg("PI/2+2PI", sin2(Math.PI / 2 + Math.PI * 2));//有精度损失
        X.lg("PI/6", sin2(Math.PI / 6));
        X.lg("PI/6+2PI", sin2(Math.PI / 6 + Math.PI * 2));//有精度损失
        X.lg("PI/4", sin2(Math.PI / 4));
        X.lg("PI/4+2PI", sin2(Math.PI / 4 + Math.PI * 2));//有精度损失
        X.lg("-PI/6", sin2(-Math.PI / 6 + Math.PI * 2));//有精度损失
        X.lg("-PI/6+2PI", sin2(-Math.PI / 6 + Math.PI * 2));//有精度损失
        X.lg("2PI", sin2(Math.PI * 2));//有精度损失
        X.lg("-2PI", sin2(Math.PI * 2));//有精度损失

        X.lg(11.0 % 88);
        X.lg(11.0 / 88);
        X.lg(11.0 / 88 * 88);
        X.lg(Math.PI / Math.PI);
        X.lg(2 * Math.PI / (2 * Math.PI));
        X.lg(-Math.PI / Math.PI);
        X.lg(-2 * Math.PI / (2 * Math.PI));

        X.lg("PI/2",cos2(Math.PI/2));
        X.lg("PI",cos2(Math.PI));
        X.lg("-PI",cos2(-Math.PI));
        X.lg("PI/6",cos2(Math.PI/6));
        X.lg("PI/3",cos2(Math.PI/3));
        X.lg("PI/4",cos2(Math.PI/4));
        X.lg("2PI",cos2(2*Math.PI));
        X.lg("0",cos2(0));
//        BigInteger bigInteger = BigInteger.valueOf(2432902008176640000L);
//        X.lg(bigInteger.multiply(BigInteger.valueOf(2432902008176640000L)));
//        X.lg(bigInteger.multiply(BigInteger.valueOf(2432902008176640000L)).doubleValue());

    }
}

sin1: 1.5707963267948966
PI/2 1.0038988590395785
sin1: 0.5235987755982988
PI/6 0.4951766393046648
sin1: 0.7853981633974483
PI/4 0.7023268134010443
0.7071067811865475
sin2: 1.5707963267948966
sin2.cnt: 9
PI/2 1.0
sin2: 1.5707963267948966
sin2.cnt: 9
PI/2+2PI 1.0
sin2: 0.5235987755982988
sin2.cnt: 6
PI/6 0.5
sin2: 0.5235987755982991
sin2.cnt: 6
PI/6+2PI 0.5000000000000003
sin2: 0.7853981633974483
sin2.cnt: 7
PI/4 0.7071067811865475
sin2: 0.7853981633974483
sin2.cnt: 7
PI/4+2PI 0.7071067811865475
sin2: 5.759586531581287
sin2.cnt: 9
-PI/6 -0.5001706202630702
sin2: 5.759586531581287
sin2.cnt: 9
-PI/6+2PI -0.5001706202630702
sin2: 0.0
sin2.cnt: 0
2PI 0.0
sin2: 0.0
sin2.cnt: 0
-2PI 0.0
11.0
0.125
11.0
1.0
1.0
-1.0
-1.0
cos2: 1.5707963267948966
cos2.cnt: 10
PI/2 6.08176268469988E-17
cos2: 3.141592653589793
cos2.cnt: 10
PI -0.9999999999243493
cos2: 3.141592653589793
cos2.cnt: 10
-PI -0.9999999999243493
cos2: 0.5235987755982988
cos2.cnt: 7
PI/6 0.8660254037844386
cos2: 1.0471975511965976
cos2.cnt: 8
PI/3 0.5000000000000004
cos2: 0.7853981633974483
cos2.cnt: 8
PI/4 0.7071067811865475
cos2: 0.0
cos2.cnt: 0
2PI 1.0
cos2: 0.0
cos2.cnt: 0
0 1.0


精度有问题 用BigDecimal解决

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值