c – 什么时候在`std :: sqrt(x * x y * y)’上使用`std :: hypo
documentation of
std::hypot 说:
我很难想象一个测试用例,其中std :: hypot应该用于平凡的sqrt(x * x y * y). 以下测试显示,std :: hypot比原始计算慢约20倍. #include <iostream> #include <chrono> #include <random> #include <algorithm> int main(int,char**) { std::mt19937_64 mt; const auto samples = 10000000; std::vector<double> values(2 * samples); std::uniform_real_distribution<double> urd(-100.0,100.0); std::generate_n(values.begin(),2 * samples,[&]() {return urd(mt); }); std::cout.precision(15); { double sum = 0; auto s = std::chrono::steady_clock::now(); for (auto i = 0; i < 2 * samples; i += 2) { sum += std::hypot(values[i],values[i + 1]); } auto e = std::chrono::steady_clock::now(); std::cout << std::fixed <<std::chrono::duration_cast<std::chrono::microseconds>(e - s).count() << "us --- s:" << sum << std::endl; } { double sum = 0; auto s = std::chrono::steady_clock::now(); for (auto i = 0; i < 2 * samples; i += 2) { sum += std::sqrt(values[i]* values[i] + values[i + 1]* values[i + 1]); } auto e = std::chrono::steady_clock::now(); std::cout << std::fixed << std::chrono::duration_cast<std::chrono::microseconds>(e - s).count() << "us --- s:" << sum << std::endl; } } 所以我要求指导,什么时候我必须使用std :: hypot(x,y)通过更快的std :: sqrt(x * x y * y)获得正确的结果. 澄清:当x和y是浮点数时,我正在寻找适用的答案.即比较: double h = std::hypot(static_cast<double>(x),static_cast<double>(y)); 至: double xx = static_cast<double>(x); double yy = static_cast<double>(y); double h = std::sqrt(xx*xx + yy*yy); 解决方法
答案是在您引用的文档中
如果x * x y * y溢出,那么如果手动进行计算,则会得到错误的答案.但是,如果使用std :: hypot,则可以保证中间计算不会溢出. 你可以看到这个差距的一个例子here. 如果您正在使用的数字,您知道不会溢出您的平台相关的代表,您可以高兴地使用天真的版本. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |