-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

        Hi Sven,

Sven de Marothy wrote:
> On Wed, 2006-08-02 at 20:27 +0200, Carsten Neumann wrote:
>> this adds another missing method to StrictMath, mauve test is already in.
>> Comments or approval, appreciated.
> 
> Seems just fine to me. Just two minor points:
> (This being _strict_ math, after all. ;))
> 1) l_bits is unused.

thanks, for spotting this, fixed in the attached.

> 2) If a random NaN number is passed in, the JDK returns that number, and
> not the NaN constant.

This is fixed for tanh in the attached updated version.
I'll post a seperate patch to fix this for the other methods I
implemented recently.

        Thanks,
                Carsten

Committed as:

2006-08-03  Carsten Neumann  <[EMAIL PROTECTED]>

        * java/lang/StrictMath.java (tanh): New method.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFE0kLGd4NEZjs4PvgRAiHUAJ9zppes1lqzMXtDNVL4uUcoTUuEXACfSRg2
OKEyntgPd0cbQsh25gOiO/M=
=4N2h
-----END PGP SIGNATURE-----
Index: cp/classpath/java/lang/StrictMath.java
===================================================================
--- cp.orig/classpath/java/lang/StrictMath.java	2006-08-02 19:17:29.000000000 +0200
+++ cp/classpath/java/lang/StrictMath.java	2006-08-03 19:53:23.000000000 +0200
@@ -814,6 +814,75 @@
   }
 
   /**
+   * Returns the hyperbolic tangent of <code>x</code>, which is defined as
+   * (exp(x) - exp(-x)) / (exp(x) + exp(-x)), i.e. sinh(x) / cosh(x).
+   *
+   Special cases:
+   * <ul>
+   * <li>If the argument is NaN, the result is NaN</li>
+   * <li>If the argument is positive infinity, the result is 1.</li>
+   * <li>If the argument is negative infinity, the result is -1.</li>
+   * <li>If the argument is zero, the result is zero.</li>
+   * </ul>
+   *
+   * @param x the argument to <em>tanh</em>
+   * @return the hyperbolic tagent of <code>x</code>
+   *
+   * @since 1.5
+   */
+  public static double tanh(double x)
+  {
+    //  Method :
+    //  0. tanh(x) is defined to be (exp(x) - exp(-x)) / (exp(x) + exp(-x))
+    //  1. reduce x to non-negative by tanh(-x) = -tanh(x).
+    //  2.  0     <= x <= 2^-55 : tanh(x) := x * (1.0 + x)
+    //                                        -t
+    //      2^-55 <  x <= 1     : tanh(x) := -----; t = expm1(-2x)
+    //                                       t + 2
+    //                                              2
+    //      1     <= x <= 22.0  : tanh(x) := 1 -  ----- ; t=expm1(2x)
+    //                                            t + 2
+    //     22.0   <  x <= INF   : tanh(x) := 1.
+
+    double t, z;
+
+    long bits;
+    long h_bits;
+
+    // handle special cases
+    if (x != x)
+      return x;
+    if (x == Double.POSITIVE_INFINITY)
+      return 1.0;
+    if (x == Double.NEGATIVE_INFINITY)
+      return -1.0;
+
+    bits = Double.doubleToLongBits(x);
+    h_bits = getHighDWord(bits) & 0x7fffffffL;  // ingnore sign
+
+    if (h_bits < 0x40360000L)                   // |x| <  22
+      {
+	if (h_bits < 0x3c800000L)               // |x| <  2^-55
+	  return x * (1.0 + x);
+
+	if (h_bits >= 0x3ff00000L)              // |x| >= 1
+	  {
+	    t = expm1(2.0 * abs(x));
+	    z = 1.0 - 2.0 / (t + 2.0);
+	  }
+	else                                    // |x| <  1
+	  {
+	    t = expm1(-2.0 * abs(x));
+	    z = -t / (t + 2.0);
+	  }
+      }
+    else                                        // |x| >= 22
+	z = 1.0;
+
+    return (x >= 0) ? z : -z;
+  }
+
+  /**
    * Returns the lower two words of a long. This is intended to be
    * used like this:
    * <code>getLowDWord(Double.doubleToLongBits(x))</code>.

Reply via email to