Author: nick Date: Sat Feb 14 22:48:29 2009 New Revision: 744579 URL: http://svn.apache.org/viewvc?rev=744579&view=rev Log: Implement JavaME compatible log and log10 functions
Modified: commons/sandbox/me/trunk/src/org/apache/commons/me/math/MoreMath.java commons/sandbox/me/trunk/test-src/org/apache/commons/me/math/TestMoreMath.java Modified: commons/sandbox/me/trunk/src/org/apache/commons/me/math/MoreMath.java URL: http://svn.apache.org/viewvc/commons/sandbox/me/trunk/src/org/apache/commons/me/math/MoreMath.java?rev=744579&r1=744578&r2=744579&view=diff ============================================================================== --- commons/sandbox/me/trunk/src/org/apache/commons/me/math/MoreMath.java (original) +++ commons/sandbox/me/trunk/src/org/apache/commons/me/math/MoreMath.java Sat Feb 14 22:48:29 2009 @@ -42,6 +42,66 @@ static final double q1 = 2079.33497444540981287275926; static final double q0 = 896.78597403663861962481162; + // There are all used by the log function + static final double log10 = 2.3025850929940459; + static final double logHalf = -0.69314718055994529; + + /** + * Implement log (natural log), using Taylor + * series expansion + */ + public static double log(double val) { + if(val > 0.0) { + // Good + } else if(val == 1.0) { + // Easy + return 0.0; + } else { + // Log doesn't exist for this + return Double.NaN; + } + + if(val < 1.0) { + return _log(val); + } else { + // if x > 1, then + // log(x) == -log(1/x) + return 0 - _log( (1/val) ); + } + } + /** + * Implements the base 10 logarithm + */ + public static double log10(double val) { + return log(val) / log10; + } + /** + * Does the actual taylor series for 0 < x < 1 + */ + private static double _log(double val) { + double res = 0; + double sign = 1.0; + double val_m1 = val - 1.0; + + // 50 times is normally ok if the value + // is over 0.06, otherwise up to 90 + int steps = 50; + if(val < 0.06) { steps = 90; } + + for(int i=1; i<=steps; i++) { + // Raise to the power + double t = val_m1; + for(int j=2; j<=i; j++) { + t = t * val_m1; + } + // Combine + res = res + sign*(t / ((double)i)); + // Flip sign for next time + sign = sign * -1; + } + return res; + } + /** * Implement the asin (arc-sine) function */ Modified: commons/sandbox/me/trunk/test-src/org/apache/commons/me/math/TestMoreMath.java URL: http://svn.apache.org/viewvc/commons/sandbox/me/trunk/test-src/org/apache/commons/me/math/TestMoreMath.java?rev=744579&r1=744578&r2=744579&view=diff ============================================================================== --- commons/sandbox/me/trunk/test-src/org/apache/commons/me/math/TestMoreMath.java (original) +++ commons/sandbox/me/trunk/test-src/org/apache/commons/me/math/TestMoreMath.java Sat Feb 14 22:48:29 2009 @@ -29,6 +29,33 @@ 1.1, 10, 20, 100, 1000, Math.PI, -1.4, -20 }; + public void testLog() { + // Valid range + assertTrue( Double.isNaN( MoreMath.log( -1.0 ) ) ); + assertEquals(0.0, MoreMath.log(1.0)); + + // sub 1 + assertEquals(-2.30258509, MoreMath.log(0.1), 0.001); + assertEquals(-0.69314718, MoreMath.log(0.5), 0.001); + assertEquals(-0.10536051, MoreMath.log(0.9), 0.001); + + // greater than one + assertEquals(0.69314718, MoreMath.log(2.0), 0.001); + assertEquals(1.60943791, MoreMath.log(5.0), 0.001); + assertEquals(2.30258509, MoreMath.log(10.0), 0.001); + assertEquals(2.99573227, MoreMath.log(20.0), 0.002); + } + + public void testLog10() { + // Valid range + assertTrue( Double.isNaN( MoreMath.log( -1.0 ) ) ); + assertEquals(0.0, MoreMath.log(1.0)); + + // Just a few + assertEquals(1.00000, MoreMath.log10(10.0), 0.001); + assertEquals(1.30103, MoreMath.log10(20.0), 0.001); + } + public void testASin() { for(int i=0; i<testArcVals.length; i++) { assertEquals(