This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

pow(double, int)


I resurrected an pow(*, int) code for use in libstdc++, unless someone
has an even faster one lying around.  As seen from the benchmark it
improves
performance, especially for small exponents, but also gives 2x for large
exponents.

I was confused by the headers; `shadow/bits/std_cmath.h' is meant
to become a _replacement_ for `bits/std_cmath.h', right?

Cheers,
-petter.


2000-04-05  Petter Urkedal  <petter@matfys.lth.se>

	* src/cmath.cc: New file...
	(pow(*, int)): Define functions...
	* src/Makefile.am (sources): ...register file.
	* src/Makefile.in: Regenerate.
	* bits/std_cmath.h (pow): ...declare functions here, and remove
	old definitions.



Testing float versions:
pow(    -0.505,         1):  0.04 s 0.4 s
pow( -0.504005,        -1):  0.06 s 0.39 s
pow( -0.462953,        10):  0.08 s 0.39 s
pow( -0.326591,       -10):  0.09 s 0.43 s
pow( -0.136752,       100):  0.32 s 0.65 s
pow( -0.412756,      -100):  0.11 s 0.45 s
pow( -0.411779,      1000):  0.36 s 0.83 s
pow(-0.0129106,     -1000):  0.17 s 0.8 s
pow( 0.0270178,     10000):  0.41 s 0.91 s
pow(-0.0460222,    -10000):  0.45 s 0.85 s
pow(  -0.26949,    100000):  0.46 s 1.01 s
pow(  0.334605,   -100000):  0.46 s 0.91 s
pow(  0.436049,   1000000):  0.53 s 1.07 s
pow( 0.0687402,  -1000000):  0.58 s 1.01 s
pow( 0.0566553,  10000000):  0.68 s 1.26 s
pow(  -0.45366, -10000000):  0.7 s 1.19 s
pow(  0.269722, 100000000):  0.63 s 1.28 s
pow( -0.485896,-100000000):  0.7 s 1.22 s
pow( -0.250117,1000000000):  0.73 s 1.37 s
pow( -0.203821,-1000000000):  0.74 s 1.15 s
pow(  0.379741,-2147483648):  0.56 s 0.93 s
pow( 0.0318724,-2147483648):  0.58 s 0.94 s
Check if they agree at the singularity:
  pow(0.0, 0) = 1
  pow(0.0, 0.0) =  1

Testing double versions:
pow(  0.424464,         1):  0.07 s 0.35 s
pow( 0.0155855,        -1):  0.11 s 0.36 s
pow(  0.313534,        10):  0.11 s 0.37 s
pow( -0.314696,       -10):  0.14 s 0.39 s
pow(  0.390178,       100):  0.13 s 0.42 s
pow( 0.0713202,      -100):  0.21 s 0.42 s
pow( -0.427458,      1000):  0.37 s 0.81 s
pow(  0.318427,     -1000):  0.2 s 0.68 s
pow(   0.48974,     10000):  0.39 s 1.05 s
pow( -0.385465,    -10000):  0.26 s 0.8 s
pow(  0.397845,    100000):  0.49 s 1.04 s
pow(  0.287328,   -100000):  0.56 s 0.88 s
pow( -0.403075,   1000000):  0.62 s 1.13 s
pow( -0.249156,  -1000000):  0.8 s 1.02 s
pow(  -0.48496,  10000000):  0.7 s 1.21 s
pow( -0.122839, -10000000):  0.97 s 1.13 s
pow(  0.180666, 100000000):  0.68 s 1.14 s
pow(  0.182732,-100000000):  0.67 s 0.99 s
pow(  0.255234,1000000000):  0.69 s 1.21 s
pow( -0.498708,-1000000000):  1.09 s 1.15 s
pow(  0.125651,-2147483648):  0.58 s 0.9 s
pow( -0.377273,-2147483648):  0.58 s 0.96 s
Check if they agree at the singularity:
  pow(0.0, 0) = 1
  pow(0.0, 0.0) =  1
// -*- C++ -*- C math library.

// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

//
// ISO C++ 14882: 26.5  C library
// Code for signatures not found in the C library
//

#include <bits/std_cmath.h>


namespace std
{

  namespace {
    template <typename T>
    inline T pow_helper(T x, unsigned int y)
    {
      T z = y&1? x : 1;
      while(y >>= 1)
	{
	  x *= x;
	  if(y & 1) z *= x;
	}
      return z;
    }
  }

  float
  pow(float x, int y)
  {
    if(y < 0)
      return 1.0f/pow_helper(x, -y);
    else
      return pow_helper(x, y);
  }

  double
  pow(double x, int y)
  {
    if(y < 0)
      return 1.0/pow_helper(x, -y);
    else
      return pow_helper(x, y);
  }

  long double
  pow(long double x, int y)
  {
    if(y < 0)
      return 1.0l/pow_helper(x, -y);
    else
      return pow_helper(x, y);
  }

}
Index: bits/std_cmath.h
===================================================================
RCS file: /cvs/libstdc++/libstdc++/bits/std_cmath.h,v
retrieving revision 1.18
diff -c -r1.18 std_cmath.h
*** std_cmath.h 2000/03/21 06:24:04     1.18
--- std_cmath.h 2000/04/04 23:03:10
***************
*** 52,59 ****
      inline double
      abs(double __x) { return ::fabs(__x); }
  
!     inline double
!     pow(double __x, int __i) { return ::pow(__x, static_cast<double>(__i)); }
  
      // float
      inline float
--- 52,59 ----
      inline double
      abs(double __x) { return ::fabs(__x); }
  
!     double
!     pow(double, int);
  
      // float
      inline float
***************
*** 78,86 ****
      pow(float __x, float __y) 
      { return ::pow(static_cast<double>(__x), static_cast<double>(__y)); }
  
!     inline float
!     pow(float __x, int __i) 
!     { return ::pow(static_cast<double>(__x), static_cast<double>(__i)); }
  
  #if _GLIBCPP_HAVE_ABSF
      inline float
--- 78,85 ----
      pow(float __x, float __y) 
      { return ::pow(static_cast<double>(__x), static_cast<double>(__y)); }
  
!     float
!     pow(float, int);
  
  #if _GLIBCPP_HAVE_ABSF
      inline float
***************
*** 239,244 ****
--- 238,246 ----
  
  
      // XXX long double
+ 
+     long double
+     pow(long double, int);
  
  } // std
  

bench_cmath.tgz


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]