Leo 发表于 2014-5-13 14:14:00

代码评析(系列四)

来自系列三同样的一份作品,
public static double sin( double x )
    {
      x = x % ( 2 * PI ) ;
      double sum = 0 ;
      for( int i = 1 ; i < 27 ; i = i + 2 )
            sum += pow( -1 , i / 2 ) * pow( x , i ) / fact( i ) ;
      return sum ;
    }
public static double pow( double x , double nPower )
    {
      if( x > 0.0 )
            return exp( nPower * ln ( x ) ) ;
      else if( fabs( x - 0.0 ) < 0.0000001 )
            return 0.0 ;
      else
      {
            if( nPower % 2 != 0 )
                return -1 * exp( nPower * ln( -1 * x ) ) ;
            else
                return exp( nPower * ln( -1 * x ) ) ;
      }
    }
public static double exp( double x )
    {
      double sum = 1 ;
      for( int i = 1000 ; i > 0 ; i -- )
      {
            sum /= i ;
            sum *= x ;
            sum += 1 ;
      }
      return sum ;
    }

欢迎讨论。

perftcc 发表于 2014-5-13 23:39:00

怎么看见都是用java写的,难道除了我没人用c?

Leo 发表于 2014-5-14 08:54:00

有啊,入围复审的有三份C作品,貌似全部作品中,纯C语言的作品有10份左右,其他很多有用C++的。
C语言的作品,目前总体看最大的问题是错误处理。

perftcc 发表于 2014-5-15 08:51:00

我的东西就是拿c写的,感觉精度和错误检测是两个很难啃的骨头,尤其是精度,后面实在没办法只能用double类型数据,然后精度就低的可怜了,,,

Leo 发表于 2014-5-15 08:53:00

没有人点评?
那我来吧,这份作品尝试自己通过一些公式组合实现数值计算。
但是这里作者没有考虑一个问题,如果使用一个不精确的exp,计算出另一个不甚精确的POW,再拿来算三角函数,结果的误差可能会被放大无限倍。
这就是为什么经典的数值计算不会推荐你用乘方运算计算三角函数,而是使用展开式无限逼近的方法,以快速收敛和减少误差的放大。

Leo 发表于 2014-5-15 08:54:00

另:
出题的时候我考虑再三,把反双曲函数从题目中干掉了,原因很简单,目前没有一个好的,快速收敛的展开式可以计算反双曲函数,所以,我计算了一下时间,把这个复杂度摘掉了。
页: [1]
查看完整版本: 代码评析(系列四)