public static double tanh(double x){
  boolean negate=false;
  if (Double.isNaN(x)) {
    return x;
  }
  if (x > 20.0) {
    return 1.0;
  }
  if (x < -20) {
    return -1.0;
  }
  if (x == 0) {
    return x;
  }
  if (x < 0.0) {
    x=-x;
    negate=true;
  }
  double result;
  if (x >= 0.5) {
    double hiPrec[]=new double[2];
    exp(x * 2.0,0.0,hiPrec);
    double ya=hiPrec[0] + hiPrec[1];
    double yb=-(ya - hiPrec[0] - hiPrec[1]);
    double na=-1.0 + ya;
    double nb=-(na + 1.0 - ya);
    double temp=na + yb;
    nb+=-(temp - na - yb);
    na=temp;
    double da=1.0 + ya;
    double db=-(da - 1.0 - ya);
    temp=da + yb;
    db+=-(temp - da - yb);
    da=temp;
    temp=da * HEX_40000000;
    double daa=da + temp - temp;
    double dab=da - daa;
    double ratio=na / da;
    temp=ratio * HEX_40000000;
    double ratioa=ratio + temp - temp;
    double ratiob=ratio - ratioa;
    ratiob+=(na - daa * ratioa - daa * ratiob - dab * ratioa - dab * ratiob) / da;
    ratiob+=nb / da;
    ratiob+=-db * na / da / da;
    result=ratioa + ratiob;
  }
 else {
    double hiPrec[]=new double[2];
    expm1(x * 2.0,hiPrec);
    double ya=hiPrec[0] + hiPrec[1];
    double yb=-(ya - hiPrec[0] - hiPrec[1]);
    double na=ya;
    double nb=yb;
    double da=2.0 + ya;
    double db=-(da - 2.0 - ya);
    double temp=da + yb;
    db+=-(temp - da - yb);
    da=temp;
    temp=da * HEX_40000000;
    double daa=da + temp - temp;
    double dab=da - daa;
    double ratio=na / da;
    temp=ratio * HEX_40000000;
    double ratioa=ratio + temp - temp;
    double ratiob=ratio - ratioa;
    ratiob+=(na - daa * ratioa - daa * ratiob - dab * ratioa - dab * ratiob) / da;
    ratiob+=nb / da;
    ratiob+=-db * na / da / da;
    result=ratioa + ratiob;
  }
  if (negate) {
    result=-result;
  }
  return result;
}

public static double tanh ( double x ) { boolean negate = false ; if ( Double . isNaN ( x ) ) { return x ; } if ( x > 20.0 ) { return 1.0 ; } if ( x < - 20 ) { return - 1.0 ; } if ( x == 0 ) { return x ; } if ( x < 0.0 ) { x = - x ; negate = true ; } double result ; if ( x >= 0.5 ) { double hiPrec [ ] = new double [ 2 ] ; exp ( x * 2.0 , 0.0 , hiPrec ) ; double ya = hiPrec [ 0 ] + hiPrec [ 1 ] ; double yb = - ( ya - hiPrec [ 0 ] - hiPrec [ 1 ] ) ; double na = - 1.0 + ya ; double nb = - ( na + 1.0 - ya ) ; double temp = na + yb ; nb += - ( temp - na - yb ) ; na = temp ; double da = 1.0 + ya ; double db = - ( da - 1.0 - ya ) ; temp = da + yb ; db += - ( temp - da - yb ) ; da = temp ; temp = da * HEX_40000000 ; double daa = da + temp - temp ; double dab = da - daa ; double ratio = na / da ; temp = ratio * HEX_40000000 ; double ratioa = ratio + temp - temp ; double ratiob = ratio - ratioa ; ratiob += ( na - daa * ratioa - daa * ratiob - dab * ratioa - dab * ratiob ) / da ; ratiob += nb / da ; ratiob += - db * na / da / da ; result = ratioa + ratiob ; } else { double hiPrec [ ] = new double [ 2 ] ; expm1 ( x * 2.0 , hiPrec ) ; double ya = hiPrec [ 0 ] + hiPrec [ 1 ] ; double yb = - ( ya - hiPrec [ 0 ] - hiPrec [ 1 ] ) ; double na = ya ; double nb = yb ; double da = 2.0 + ya ; double db = - ( da - 2.0 - ya ) ; double temp = da + yb ; db += - ( temp - da - yb ) ; da = temp ; temp = da * HEX_40000000 ; double daa = da + temp - temp ; double dab = da - daa ; double ratio = na / da ; temp = ratio * HEX_40000000 ; double ratioa = ratio + temp - temp ; double ratiob = ratio - ratioa ; ratiob += ( na - daa * ratioa - daa * ratiob - dab * ratioa - dab * ratiob ) / da ; ratiob += nb / da ; ratiob += - db * na / da / da ; result = ratioa + ratiob ; } if ( negate ) { result = - result ; } return result ; }
compute the hyperbolic tangent of a number .
