Reputation: 5332
I have come across some old code that computes
double y = 1 / std::sqrt(x);
Using:
constexpr double base16 = 16.0;
double log_base16 = std::log(base16);
double y = std::pow(base16, -0.5 * std::log(x) / log_base16);
Which is essentially:
double y = std::exp(-0.5 * std::log(x));
Is there any justifications with regard to numerical benefits (such as accuracy or more likely to avoid underflow/overflow) between the methods? The original author may have thought so.
Upvotes: 4
Views: 357
Reputation: 6906
I can't see any particularly good reasons for implementing sqrt() in terms of pow() and log(). It could be that there was a bug in the implementation of sqrt() and this was used as a workaround.
In general, I would expect this implementation to be slower and less precise.
Upvotes: 0
Reputation: 234715
The original code is to be considered to be very naughty indeed, particularly in modern C++ standards and IEEE754 floating point:
std::sqrt is required by the IEEE standard be exact. [sic.]
Furthermore, std::pow
has no such requirements.
Therefore I'd be tempted to rewrite it as 1 / std::sqrt(x)
, testing of course.
Reference: http://en.cppreference.com/w/cpp/numeric/math/sqrt
Upvotes: 2