2010-02-03 18 views
12

मुझे यह जानकर उत्सुकता है कि दृश्य के पीछे क्या होता है, जो डबल से int को परिवर्तित करने के लिए होता है, int (5666.1) कहता है? क्या यह माता-पिता को बाल वर्ग के स्थैतिक_कास्ट से अधिक महंगा होने जा रहा है? चूंकि int और double का प्रतिनिधित्व मौलिक रूप से अलग है, इसलिए प्रक्रिया के दौरान और महंगे भी बने अस्थायी होने जा रहे हैं।दृश्य के पीछे दो से int रूपांतरण?

उत्तर

18

देशी फ्लोटिंग पॉइंट वाले किसी भी सीपीयू में फ़्लोटिंग-पॉइंट को पूर्णांक डेटा में कनवर्ट करने का निर्देश होगा। वह ऑपरेशन कुछ चक्रों से कई चक्रों में ले सकता है। आम तौर पर एफपी और पूर्णांक के लिए अलग-अलग सीपीयू रजिस्ट्रार होते हैं, इसलिए इसे उपयोग करने से पहले आपको पूर्णांक को पूर्णांक रजिस्टर में भी ले जाना होगा। यह एक और ऑपरेशन हो सकता है, संभवतः महंगा। अपने प्रोसेसर मैनुअल देखें।

पावरपीसी विशेष रूप से एक पूर्णांक रजिस्टर में एक एफपी रजिस्टर में एक पूर्णांक को स्थानांतरित करने के लिए निर्देश शामिल नहीं करता है। एफपी से मेमोरी तक स्टोर होना चाहिए और पूर्णांक तक लोड होना चाहिए। इसलिए आप कह सकते हैं कि एक अस्थायी चर बनाया गया है।

कोई हार्डवेयर एफपी समर्थन के मामले में, संख्या को डीकोड किया जाना है। आईईईई एफपी प्रारूप है:

sign | exponent + bias | mantissa 

बदलने के लिए, आप की तरह

// Single-precision format values: 
int const mantissa_bits = 23; // 52 for double. 
int const exponent_bits = 8; // 11 for double. 
int const exponent_bias = 127; // 1023 for double. 

std::int32_t ieee; 
std::memcpy(& ieee, & float_value, sizeof (std::int32_t)); 
std::int32_t mantissa = ieee & (1 << mantissa_bits)-1 | 1 << mantissa_bits; 
int exponent = (ieee >> mantissa_bits & (1 << exponent_bits)-1) 
      - (exponent_bias + mantissa_bits); 
if (exponent <= -32) { 
    mantissa = 0; 
} else if (exponent < 0) { 
    mantissa >>= - exponent; 
} else if (exponent + mantissa_bits + 1 >= 32) { 
    overflow(); 
} else { 
    mantissa <<= exponent; 
} 
if (ieee < 0) mantissa = - mantissa; 
return mantissa; 

अर्थात, और कुछ थोड़ा खोल दिए गए निर्देशों और एक पारी कुछ करने के लिए।

4

हमेशा एक समर्पित एफपीयू निर्देश है जो काम पूरा करता है, cvttsd2si अगर कोड जेनरेटर इंटेल एसएसई 2 निर्देश सेट का उपयोग करता है। यह तेज़ है, लेकिन एक स्थिर कलाकार के रूप में तेज़ नहीं है। आमतौर पर किसी भी कोड की आवश्यकता नहीं होती है।

4

static_cast कंपाइलर की सी ++ कोड पीढ़ी पर निर्भर है, लेकिन आम तौर पर कोई रनटाइम लागत नहीं होती है, क्योंकि पॉइंटर परिवर्तन की गणना कास्ट में अनुमानित जानकारी के आधार पर संकलित समय पर की जाती है।

जब आप एक x86 सिस्टम पर डबल से int परिवर्तित करते हैं, तो संकलक FIST (फ़्लोटिंग-प्वाइंट/इंटीजर रूपांतरण) निर्देश उत्पन्न करेगा, और एफपीयू रूपांतरण करेगा। यह रूपांतरण सॉफ़्टवेयर में कार्यान्वित किया जा सकता है, और कुछ हार्डवेयर पर इस तरह किया जाता है, या यदि प्रोग्राम को इसकी आवश्यकता होती है। GNU MPFR लाइब्रेरी डबल टू इंट रूपांतरण करने में सक्षम है, और सभी हार्डवेयर पर एक ही रूपांतरण करेगा।

+1

एक आधुनिक x86 के लिए, संकलक एक एसएसई 2 निर्देश उत्पन्न कर सकता है, न कि x87। – MSalters

+0

@MSalters: निर्भर करता है; कुछ "आधुनिक" कंपाइलर अभी भी डिफ़ॉल्ट रूप से x87 एफपीयू को कोडेजन करते हैं, लेकिन हाँ, कई कंपाइलर्स 'cvttsd2si' उत्सर्जित करेंगे। –

+0

हां, x86-32 पर आप केवल 'cvttsd2si' मान नहीं सकते हैं। लेकिन क्या ऐसे कंपाइलर्स हैं जो x86-64 के लिए बहिष्कृत x87 इन्स का उपयोग करते हैं? – MSalters

संबंधित मुद्दे