documentation of std::hypot
का कहना है कि:`जब उपयोग करने के लिए std :: hypot (एक्स, वाई)` `से अधिक std :: sqrt (एक्स * x + y * वाई)`
का वर्गमूल गणना करता है गणना के मध्यवर्ती चरणों में अनुचित ओवरफ्लो या अंडरफ्लो के बिना एक्स और वाई के वर्गों का योग।
मैं एक परीक्षण का मामला जहां std::hypot
तुच्छ sqrt(x*x + y*y)
से अधिक इस्तेमाल किया जाना चाहिए गर्भ धारण करने के लिए संघर्ष।
निम्नलिखित परीक्षण से पता चलता है कि std::hypot
बेकार गणना से लगभग 20x धीमी है।
#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);
मुझे लगता है कि आपको इसे 'std :: abs (std :: complex (x, y)) से तुलना करना चाहिए, जैसा कि [std :: hypot] (http://en.cppreference.com/w/ सीपीपी/न्यूमेरिक/गणित/हाइपोट) पृष्ठ –
देर हो चुकी है, लेकिन cppreference दस्तावेज़ भी एक नोट के रूप में कहता है (इसलिए मानक द्वारा कोई गारंटी नहीं) कि "कार्यान्वयन आमतौर पर 1 उल से कम (अंतिम स्थान पर इकाइयों) की सटीकता की गारंटी देता है।" 'एक्स * एक्स + वाई * वाई 'परिशुद्धता के कुछ बिट खो सकता है, अगर निकटतम सेट के साथ दौर के साथ। इसका मतलब है कि 'std :: sqrt (x * x + y * y) 'थोड़ा या दो से बंद हो सकता है। उस गारंटी प्राप्त करने के लिए 'std :: sqrt (x * x + y * y) 'से बेहतर एल्गोरिदम आवश्यक है। (जारी) –
मामलों को और भी खराब बनाने के लिए, मान लीजिए कि आपने गोल के साथ मिलकर काम किया है? वह निश्चित रूप से उस उप-उल परिशुद्धता को प्राप्त करने के तरीके में प्राप्त होगा। 'हाइपोट' को राउंडिंग सेट करना है ताकि सटीकता प्राप्त हो सके और फिर अपनी सेटिंग्स में राउंडिंग को पुनर्स्थापित कर सकें। राउंडिंग व्यवहार की यह सेटिंग और रीसेटिंग 'std: hypot (x, y) 'std :: sqrt (x * x + y * y)' से काफी धीमी है। –