我正在处理一些需要使用三角函数的编程问题.不幸的是,math.h库中的函数似乎不准确.这是一个例子:
#include <stdio.h>
#include <math.h>    
int main() {
  double a, b, c, d;
  a = sin(0.0);
  b = sin(90.0);
  c = cos(0.0);
  d = cos(90.0);
  printf("A = %lf\nB = %lf\nC = %lf\nD = %lf\n", a, b, c, d);
  return (0);
}
OUTPUT:
A = 0.000000
B = 0.893997
C = 1.000000
D = -0.448074
那么有什么方法可以使这些功能准确吗?或者我是否必须使用系列制作自己的功能?
我google了,到目前为止找不到任何方法使功能准确但使用系列.
Pas*_*uoq 12
功能sin()和cos()期望弧度.它们通常是"忠实的",也就是说,它们在数学结果的1 ULP内产生结果,至少对于高达数千的参数而言.
#include <stdio.h>
#include <math.h>    
int main() {
  double a, b, c, d;
  a = sin(0.0);
  b = sin(0.5 * 3.1415926535897932);
  c = cos(0.0);
  d = cos(0.5 * 3.1415926535897932);
  printf("A = %lf\nB = %lf\nC = %lf\nD = %lf\n", a, b, c, d);
  return (0);
}
A = 0.000000
B = 1.000000
C = 1.000000
D = 0.000000
编辑添加:
Camilo Martinez指出,"最后一位的单位"是一个专门的概念.简单来说,有一些有限double数值,密度在零附近:
++-+-+-+---+---+-------+---------------+-------------------------------+--
你计算的确切三角函数值几乎总是落在其中两个doubles 之间(唯一的例外是sin(0.0) = 0.0和cos(0.0) = 1.0):
++-+-+-+---+---+-------+---------------+-------------------------------+--
                       |    ^          |
                     lower  |       upper
                     double |       double
                            |
                   exact (mathematical) result
大多数库提供的功能在正常情况下会double直接提供精确结果或紧接数学结果.考虑到问题的难度,这是非常好的.
对于所有输入(偶数),某些库提供的函数将为您提供最接近精确结果的double 1E21.这是一个惊人的结果.直到最近,这只能以昂贵的计算成本获得,但是现在,你甚至可以获得这种结果,几乎和过去不太准确的功能一样快.
最后,有时候你甚至没有应用sin()或cos()想要的数字,而只是它最接近的数字double.一旦修复,你的例子就是这种情况:你想申请sin()和cos()π/ 2,但你不能,因为π/ 2不能表示为a double.你必须将它们应用到最近的可用double(这是固定程序所做的).
这种不准确之处可能更加复杂.他们确实给浮点计算带来了坏名声的过程,但实际上,浮点不准确性的复合方式是非常可预测的,并且在编写使用浮点的程序时可以考虑到这一点.