which method to implement exp function in c? [clos

2020-04-16 03:05发布

问题:

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 7 years ago.

I want to calculate the error of exp function under finite precision(data type is double). Is taylor series or other special algorithm?

回答1:

Generally, the best way to implement ex is by calling the exp function provided by your computing platform.

Failing this, implementing the exp function is complicated and requires several esoteric skills. An implementation typically involves:

  • Testing the input for various special cases, such as NaNs.
  • Multiplying the input by a specially prepared representation of log2e, to transform the problem from ex to 2y, where y = x • log2e.
  • Moving the integer part of y into the exponent field of a floating-point encoding.
  • Evaluating the exponential of the fractional part of y with a minimax polynomial.
  • Combining the two results above.

Additionally:

  • The minimax polynomial is engineered, often with special software, using the Remez algorithm or something similar.
  • The work must be done with some extended precision so that the final result can be calculated precisely.

Taylor series are inappropriate for evaluating functions because they are inaccurate away from their center points. This means they take too many terms to converge to the necessary precision. Having too many terms not only takes time but also makes it difficult to do the arithmetic accurately.



回答2:

While I agree with much of what Eric said in his response, there are a few points worth adding. I wrote a tool that, among other things, allows evaluation of the exponential to high (user specified) precision.

When the precision can vary, one MUST resort to tools like series approximations, since then no single polynomial approximation will suffice. Even so, there are many tricks one can employ. In fact, I was surprised by the variety of tricks I used to accelerate such a series.

A good starter reference for any such endeavor is that by Hart, "Computer Approximations", a book that is sadly not easy to find. It offers many polynomial approximations, but also talks in moderate detail about range reduction tricks.

The exponential series is itself especially interesting. I describe the methods I employed for the exponential in section 4.1 of the file HPFMod2.pdf, which is included with HPF.

As an example, to compute exp(123.456789), one might try to use a series directly, but better is to store the value of e itself. Then we can use a range reduction to compute

exp(123.456789) = exp(1)*exp(2)*exp(8)*exp(16)*exp(32)*exp(64)*exp(.456789)

We get the exponentials of powers of 2 by repeated squaring, then the fractional part will converge moderately rapidly. (E.g., 31 terms are needed for 100 digits of precision in the final series.)

However, suppose we just happened to notice that

123.456789 = 28*ln(10) + 58.9844063961667

Now, we could write the desired exponential as:

exp(123.456789) = 10^28 * exp(1)*exp(2)*exp(8)*exp(16)*exp(32)*exp(-0.0155936038332811)

As long as we know (having stored it) the value of ln(10), the final series will require only about 17 terms to achieve a desired 100 digits of precision.