2017-02-06 6 views
4

Я пришел через какой-то старый код, который вычисляетЧисленные компромиссы между 1/SQRT (х) и станд :: ехр (-0,5 * станд :: Журнал (х))

double y = 1/std::sqrt(x); 

Использование:

constexpr double base16 = 16.0; 
double log_base16 = std::log(base16); 
double y = std::pow(base16, -0.5 * std::log(x)/log_base16); 

Который по существу:

double y = std::exp(-0.5 * std::log(x)); 

есть ли какие-либо обоснования с учетом численных преимуществ (таких как точность или более вероятно, чтобы избежать сгущенного/над поток) между методами? Возможно, и оригинал автора.

+1

Сколько лет может быть? 'constexpr' был стандартизован в 2011 году. – Potatoswatter

+0

@Potatoswatte Я очистил синтаксис, чтобы сделать пример максимально понятным для людей. – keith

ответ

2

Исходный код следует считать очень непослушным на самом деле, особенно в современных стандартах C++ и IEEE754 плавающей точкой:

станд :: SQRT требуется в соответствии со стандартом IEEE быть точным. [Так в оригинале.]

Кроме того, std::pow не имеет ни одного таких требований.

Поэтому у меня возникнет соблазн переписать его как 1/std::sqrt(x), конечно же, тестирование.

Ссылка: http://en.cppreference.com/w/cpp/numeric/math/sqrt

+0

Помните, что «точный» может прийти по цене. Теоретически возможно, что альтернативный код работает быстрее. Тем не менее, это теоретически. Единственными быстрыми логарифмами являются база 2 и ее полномочия, и это также справедливо для возведения в степень. '2^(log2 (x)/2)', вероятно, намного быстрее, чем старый код. – MSalters

+0

@MSalters Конечно, xor будет быстрее, но для большинства значений будет менее точной. – Yakk

+0

@Yakk: Сокращение для 'std :: exp2 (std :: log2 (x)/2))' – MSalters

0

я не могу видеть особенно хорошие причины для реализации SQRT() в терминах мощн() и LOG(). Может быть, в реализации sqrt() возникла ошибка, и это было использовано в качестве обходного пути.

В целом, я ожидал бы, что эта реализация будет медленнее и менее точной.

+1

Учитывая '1/std :: sqrt (x)', я уверен, что мы можем предположить 'x> 0' – MSalters