public static double asinh(double a) {
		boolean negative = false;
		if (a < 0) {
			negative = true;
			a = -a;
		}

		double absAsinh;
		if (a > 0.167) {
			absAsinh = FastMath.log(FastMath.sqrt(a * a + 1) + a);
		} else {
			final double a2 = a * a;
			if (a > 0.097) {
				absAsinh = a
						* (1 - a2
								* (F_1_3 - a2
										* (F_1_5 - a2
												* (F_1_7 - a2
														* (F_1_9 - a2
																* (F_1_11 - a2
																		* (F_1_13 - a2
																				* (F_1_15 - a2
																						* F_1_17
																						* F_15_16)
																				* F_13_14)
																		* F_11_12)
																* F_9_10)
														* F_7_8) * F_5_6)
										* F_3_4) * F_1_2);
			} else if (a > 0.036) {
				absAsinh = a
						* (1 - a2
								* (F_1_3 - a2
										* (F_1_5 - a2
												* (F_1_7 - a2
														* (F_1_9 - a2
																* (F_1_11 - a2
																		* F_1_13
																		* F_11_12)
																* F_9_10)
														* F_7_8) * F_5_6)
										* F_3_4) * F_1_2);
			} else if (a > 0.0036) {
				absAsinh = a
						* (1 - a2
								* (F_1_3 - a2
										* (F_1_5 - a2
												* (F_1_7 - a2 * F_1_9 * F_7_8)
												* F_5_6) * F_3_4) * F_1_2);
			} else {
				absAsinh = a * (1 - a2 * (F_1_3 - a2 * F_1_5 * F_3_4) * F_1_2);
			}
		}

		return negative ? -absAsinh : absAsinh;
	}