学习:实现任意角度的sin、cos求值-No.2
来源:互联网 发布:在香港用淘宝 编辑:程序博客网 时间:2024/06/06 07:16
说明:
已经实现了特殊角的求值,圆周角还是使用原来的数值,能够保证每次的结果至少在小数点后10位的准确性.
学习目标:
- 使用
Math.Round
来确定double
类型的保留小数点位数
MSDN相关内容
代码实现:
窗体设计:
上面的控件只是在C#的窗体设计中使用的,关于计算sin、cos的算法是一致的。
namespace Taylor{ public partial class Form1 : Form { double Pi = 3.14159265358979; double x; public Form1() { InitializeComponent(); textBox1.Focus(); //textBox3用来测试用 //textBox3.Visible = false; } public double sin(double x) { double sin_x = 0.0; int symbol = 1; if (x < 0 || x > Pi / 2.0) { //缩小角度范围为[0, 正无穷) //sin(-a) = -sin(a) if (x < 0) { symbol *= -1; x *= -1; } //缩小角度范围为[0, 2PI) //sin(a + 2kPi) = sin(a) if ((int)(x / (2 * Pi)) != 0) x = x - (int)(x / (2 * Pi)) * (2 * Pi); //缩小角度范围为[0, 3 * Pi / 2) //sin(a + 3 * Pi / 2) = -cos(a) if ((int)(x / (3 * Pi / 2.0)) != 0) { symbol *= -1; return symbol * cos(x - (int)(x / (3 * Pi / 2.0)) * (3 * Pi / 2.0)); } //缩小角度范围为[0, Pi) //sin(a + Pi) = -sin(a) if ((int)(x / Pi) != 0) { x = x - (int)(x / Pi) * Pi; symbol *= -1; } //缩小角度范围为[0, Pi / 2) //sin(a + Pi / 2) = cos(a) if ((int)(x / (Pi / 2.0)) != 0) { return symbol * cos(x - (int)(x / (Pi / 2.0)) * Pi / 2.0); } } //这里判断使用Math.Round(double value, int digits)格式化double类型保留指定小数位 if (Math.Round(x, 10) == 0.0) return 0; else if (Math.Round(x, 10) == Math.Round(Pi / 6.0, 10)) return symbol * 0.5; else if (Math.Round(x, 10) == Math.Round(Pi / 2.0, 10)) return symbol * 1; else { for (int n = 0; n < 10; n++) //取前十次的项来计算 { double a = 1.0, b = 1.0, c = 1.0; //计算(-1)的(n)次方 for (int i = 0; i < n; i++) { a *= -1; } //计算(2n + 1)的阶乘 for (int i = 1; i <= 2 * n + 1; i++) { b *= i; } //计算(x)的(2n+1)次方 for (int i = 0; i < 2 * n + 1; i++) { c *= x; } sin_x += ((a / b) * c); } return symbol * sin_x; } } public double cos(double x) { double cos_x = 0.0; int symbol = 1; if (x < 0 || x > Pi / 2.0) { //缩小角度范围为[0, 正无穷) //cos(-a) = cos(a) if (x < 0) { x *= -1; } //缩小角度范围为[0, 2PI) //cos(a + 2kPi) = cos(a) if ((int)(x / (2 * Pi)) != 0) x = x - (int)(x / (2 * Pi)) * (2 * Pi); //缩小角度范围为[0, 3 * Pi / 2) //cos(a + 3 * Pi / 2) = sin(a) if ((int)(x / (3 * Pi / 2.0)) != 0) { return symbol * sin(x - (int)(x / (3 * Pi / 2.0)) * (3 * Pi / 2.0)); } //缩小角度范围为[0, Pi) //cos(a + Pi) = -cos(a) if ((int)(x / Pi) != 0) { symbol *= -1; x = x - (int)(x / Pi) * Pi; } //缩小角度范围为[0, Pi / 2) //cos(a + Pi / 2) = -sin(a) if ((int)(x / (Pi / 2.0)) != 0) { symbol *= -1; return symbol * sin(x - (int)(x / (Pi / 2.0)) * Pi / 2.0); } } if (Math.Round(x, 10) == 0.0) return symbol * 1; else if (Math.Round(x, 10) == Math.Round(Pi / 3.0, 10)) return symbol * 0.5; else if (Math.Round(x, 10) == Math.Round(Pi / 2.0, 10)) return 0; else { for (int n = 0; n < 10; n++) //取前十次的项来计算 { double a = 1.0, b = 1.0, c = 1.0; //计算(-1)的(n)次方 for (int i = 0; i < n; i++) { a *= -1; } //计算(2n)的阶乘 for (int i = 1; i <= 2 * n; i++) { b *= i; } //计算(x)的(2n+1)次方 for (int i = 0; i < 2 * n; i++) { c *= x; } cos_x += a * c / b; } return symbol * cos_x; } } private void button1_Click(object sender, EventArgs e) { x = Convert.ToDouble(textBox1.Text) / Convert.ToDouble(textBox2.Text) * Pi; label1.Text = "sinx = " + sin(x).ToString(); label2.Text = "cosx = " + cos(x).ToString(); textBox1.Focus(); //测试用 //textBox3.Visible = true; //for (double m = 0.0; m < 10; m++) //{ // for (double n = 1.0; n < m; n++) // { // x = m / n * Pi; // textBox3.Text += m + "/" + n + " Pi:" + cos(x).ToString() + "\r\n"; // } // textBox3.Text += "\r\n"; //} } }}
坑:
使用泰勒展开式计算特殊角得出的结果不是特殊角对应的结果,而是一个无限无限接近的值,这个时候使用
if (x == 0.0)
这种来判等的话就不能判等正确了,所以就使用了Math.Round
来缩小范围。由上得,能使用整型的时候不要使用浮点型,用了浮点型就尽量不要用来计算,要计算的时候就要特别注意啦!
那段缩小范围的代码可能由冗余的,我暂时没有更好的解决方法。
0 0
- 学习:实现任意角度的sin、cos求值-No.2
- 学习:实现任意角度的sin、cos求值-No.1
- 求一个角度的sin,cos值的demo
- 快速sin()和cos()的实现
- 三角函数sin和cos的实现
- C语言sin和cos函数的实现
- sin和cos的爱恋
- 输出sin,cos的值
- sin与cos的求法
- cos和sin的使用
- C++中cos,sin,asin,acos这些三角函数操作的是弧度,而非角度,
- C++中cos,sin,asin,acos这些三角函数操作的是弧度,而非角度
- 用sin 和cos 的泰勒展开式编程序,求出sin( π/2)、sin(56°)、cos(87°)、cos( π/3)
- 纯C实现sqrt,cos,sin,atan2
- Sin Cos 在directx中的实现
- C语言中cos(x)或sin(x),x输入的是弧度,怎么输入角度
- C++中cos,sin,asin,acos这些三角函数操作的是弧度,而非角度(转)
- xilinx dds 核 的sin and cos
- Android 编程下的 TraceView 简介及其案例实战
- 【uoj 35】后缀排序
- 总结网络IO模型与select模型的Python实例讲解
- 补码的概念
- avformat_open_input超时问题
- 学习:实现任意角度的sin、cos求值-No.2
- 关于Android的主题设置的文章
- 泛型 (中) - 解析通配符:
- OJ1914(改进,通过OJ检测)
- Socket数据通信
- Spring
- JAVA调用R语言之Rserve(二)
- openwrt启动流程
- 如何在Java程序中读写系统剪切板的数据