C ++ 03 मानक C90 मानक पर निर्भर करता है कि मानक C लाइब्रेरी को क्या कहते हैं, जो प्रारूप C ++ 03 मानक ( निकटतम सार्वजनिक रूप से उपलब्ध मसौदा मानक C ++ 03 के1.2
मानक N1804 ) के मसौदे में शामिल है, अनुभाग सामान्य संदर्भ :
ISO / IEC 9899: 1990 के खंड 7 और ISO / IEC 9899 / Amd.1: 1995 के खंड 7 में वर्णित पुस्तकालय को बाद में मानक C लाइब्रेरी कहा जाता है। 1)
यदि हम c के लिए प्रलेखन के दौर में जाते हैं, तो चारों ओर से घेरे हुए हैं, हम यह देख सकते हैं कि गोल और संबंधित कार्य C99 का हिस्सा हैं और इस प्रकार C ++ 03 या पूर्व में उपलब्ध नहीं होंगे।
C ++ 11 में, C ++ 11 के बाद से यह परिवर्तन C मानक लाइब्रेरी के लिए C99 ड्राफ्ट मानक पर निर्भर करता है और इसलिए std :: दौर प्रदान करता है और इंटीग्रल रिटर्न प्रकारों के लिए std :: lround, std :: llround :
#include <iostream>
#include <cmath>
int main()
{
std::cout << std::round( 0.4 ) << " " << std::lround( 0.4 ) << " " << std::llround( 0.4 ) << std::endl ;
std::cout << std::round( 0.5 ) << " " << std::lround( 0.5 ) << " " << std::llround( 0.5 ) << std::endl ;
std::cout << std::round( 0.6 ) << " " << std::lround( 0.6 ) << " " << std::llround( 0.6 ) << std::endl ;
}
C99 से एक अन्य विकल्प भी std :: trunc होगा :
निकटतम पूर्णांक की गणना arg से अधिक परिमाण में नहीं है।
#include <iostream>
#include <cmath>
int main()
{
std::cout << std::trunc( 0.4 ) << std::endl ;
std::cout << std::trunc( 0.9 ) << std::endl ;
std::cout << std::trunc( 1.1 ) << std::endl ;
}
आपका सर्वश्रेष्ठ दांव उपयोग होगा यदि आप गैर सी ++ समर्थन करने के लिए 11 आवेदन पत्र की जरूरत है बढ़ावा दौर, iround, lround, llround या बढ़ावा TRUNC ।
अपने स्वयं के संस्करण को रोल करना कठिन है
अपनी खुद की रोलिंग शायद इस प्रयास के लायक नहीं है क्योंकि हार्डर दिखता है: निकटतम पूर्णांक तक फ्लोटिंग, भाग 1 , निकटतम पूर्णांक के लिए फ्लोटिंग, भाग 2 और निकटतम पूर्णांक के लिए फ़्लोटिंग फ्लोटिंग, भाग 3 की व्याख्या करें:
उदाहरण के लिए एक सामान्य रोल जो आपके कार्यान्वयन का उपयोग करता है std::floor
और जोड़ना 0.5
सभी इनपुट के लिए काम नहीं करता है:
double myround(double d)
{
return std::floor(d + 0.5);
}
इसके लिए एक इनपुट विफल हो जाएगा 0.49999999999999994
, ( इसे लाइव देखें )।
एक अन्य सामान्य कार्यान्वयन में एक अस्थायी बिंदु प्रकार को एक अभिन्न प्रकार में शामिल करना शामिल है, जो उस मामले में अपरिभाषित व्यवहार को आमंत्रित कर सकता है जहां अभिन्न अंग को गंतव्य प्रकार में प्रतिनिधित्व नहीं किया जा सकता है। हम इसे C ++ मानक खंड 4.9
फ्लोटिंग-इंटीग्रल रूपांतरणों के मसौदे से देख सकते हैं, जो कहता है ( जोर मेरा ):
फ़्लोटिंग पॉइंट प्रकार के एक प्रोलव्यू को एक पूर्णांक प्रकार के एक प्रचलन में परिवर्तित किया जा सकता है। रूपांतरण ट्रंकट्स; यानी भिन्नात्मक भाग को छोड़ दिया गया है। यदि गंतव्य प्रकार में काट-छाँट किए गए मान का प्रतिनिधित्व नहीं किया जा सकता है तो व्यवहार अपरिभाषित है। [...]
उदाहरण के लिए:
float myround(float f)
{
return static_cast<float>( static_cast<unsigned int>( f ) ) ;
}
दिया गया std::numeric_limits<unsigned int>::max()
है 4294967295
तो निम्नलिखित कॉल:
myround( 4294967296.5f )
अतिप्रवाह का कारण होगा, ( इसे लाइव देखें )।
हम देख सकते हैं कि सी में राउंड () को लागू करने के लिए कॉन्सिसेज़ के इस जवाब को देखकर वास्तव में यह कितना मुश्किल है? जो एकल परिशुद्धता फ्लोट दौर के newlibs संस्करण को संदर्भित करता है । यह किसी ऐसी चीज के लिए बहुत लंबा कार्य है जो सरल लगती है। ऐसा लगता है कि अस्थायी बिंदु कार्यान्वयन के अंतरंग ज्ञान के बिना कोई भी इस समारोह को सही ढंग से लागू नहीं कर सकता है:
float roundf(x)
{
int signbit;
__uint32_t w;
/* Most significant word, least significant word. */
int exponent_less_127;
GET_FLOAT_WORD(w, x);
/* Extract sign bit. */
signbit = w & 0x80000000;
/* Extract exponent field. */
exponent_less_127 = (int)((w & 0x7f800000) >> 23) - 127;
if (exponent_less_127 < 23)
{
if (exponent_less_127 < 0)
{
w &= 0x80000000;
if (exponent_less_127 == -1)
/* Result is +1.0 or -1.0. */
w |= ((__uint32_t)127 << 23);
}
else
{
unsigned int exponent_mask = 0x007fffff >> exponent_less_127;
if ((w & exponent_mask) == 0)
/* x has an integral value. */
return x;
w += 0x00400000 >> exponent_less_127;
w &= ~exponent_mask;
}
}
else
{
if (exponent_less_127 == 128)
/* x is NaN or infinite. */
return x + x;
else
return x;
}
SET_FLOAT_WORD(x, w);
return x;
}
दूसरी ओर, यदि कोई अन्य समाधान प्रयोग करने योग्य नहीं है तो newlib संभावित रूप से एक विकल्प हो सकता है क्योंकि यह एक अच्छी तरह से परीक्षण किया गया कार्यान्वयन है।
std::cout << std::fixed << std::setprecision(0) << -0.9
उदाहरण के लिए कर सकते हैं ।