2010-05-05 24 views
23

क्या इनट्स या हस्ताक्षरित इंकों के लिए फ्लोट मैप करने का कोई तरीका है ताकि NaN के अपवाद के साथ, आदेश संरक्षित हो?32 बिट पूर्णांक पर 32 बिट फ्लोट को मानचित्र करें

तो अगर ए और बी तैरता है, और एफ, मानचित्रण समारोह है

एक < ख एफ (क) < एफ (ख) और एक == ख का तात्पर्य एफ का तात्पर्य (क) == एफ (ख)

+0

हाँ, मुझे लगता है कि मैंने पहले इस तरह के एक मानचित्रण देखा है - यह था काफी चालाक - मैं बस चाहता हूं कि मुझे याद आए * जहां * मैंने इसे देखा ... –

+0

क्या मैं इस तरह के मैपिंग के लिए आपके उपयोग के मामले से पूछ सकता हूं? –

+3

+1 महान प्रश्न –

उत्तर

12

हम्म, बस खेल प्रोग्रामिंग रत्न 6 में DawsonCompare दिनचर्या से बाहर है, यह एक सामान्य सा कलाकारों निशानी फ्लिप के बाद है (के बाद से नकारात्मक तैरता विपरीत तो नकारात्मक पूर्णांक आदेश)। मैं उस विचार को उधार लेगा।

आपके पास:

// utility 
template <typename R, typename T> 
R& bit_cast(T& pX) 
{ 
    return reinterpret_cast<R&>(pX); 
} 

// int32_t defined in <boost/cstdint.hpp>. 
boost::int32_t float_to_int_bits(float pX) 
{ 
    boost::int32_t x = bit_cast<boost::int32_t>(pX); 

    if (x < 0) 
     x = 0x80000000 - x; 

    return x; 
} 

आप अपने int है 32 बिट गारंटी ले सकते हैं, तो आप बस का उपयोग कर सकते हैं।


मज़ेदार तथ्य: पुस्तक (, टिप्पणी, सटीक कोड मैं उपस्थित साथ नहीं के बाद से मैं नाव-टू-पूर्णांक भाग बाहर छीन) इस का उपयोग करने के सहिष्णुता के साथ चल बिन्दु मानों की तुलना करने पर चला जाता है:

bool DawsonCompare(float pX, float pY, int pDiff) 
{ 
    int x = float_to_int_bits(pX); 
    int y = float_to_int_bits(pY); 

    int diff = x - y; 
    return abs(diff) < pDiff; 
} 

यह तुलना पूरी तरह से तैरती है यदि उनके पूर्णांक प्रतिनिधित्व एक निश्चित सीमा के भीतर हैं। (वह 1000 को एक अच्छे डिफ़ॉल्ट के रूप में उपयोग करता है।) LomontCompare नामक शाखा-कम संस्करण को एक ही विचार के साथ प्रस्तुत किया जाता है, लेकिन आपको इसके लिए पुस्तक खरीदनी होगी। :)

+5

+1 यहां एक महान संबंधित लिंक है: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm –

+1

मदद – zounds

1

बस अन्य उत्तर से संभावित धीमी if खत्म करने के लिए ...

int32_t float_to_int(float f) { 
    int32_t i = reinterpret_cast< int32_t& >(f); 
    uint32_t sgn = static_cast<uint32_t>(i) >> 31; 

    return i^-sgn & numeric_limits<int32_t>::max(); 
} 

ध्यान दें कि अन्य समाधान के विपरीत, ये गलत तरीके से 0 और -0 संभालती है। फ्लोट के रूप में वे बराबर की तुलना करते हैं, लेकिन पूर्णांक में मैपिंग के बाद वे क्रमश: 0 और -1 बन जाते हैं। संख्या रेखा में एक ही हिचकी के रूप में, मुझे नहीं लगता कि शाखा निर्देश के बिना उस मामले को संभालना आसान होगा।

बेशक

, इस दो के पूरक गणित, float जा रहा है आईईईई 754 एकल, एक ही endianness और एक ही पता स्थान तैरता और ints के लिए, आदि मान लिया गया

+0

सहायता के लिए धन्यवाद जीएमएन का समाधान सकारात्मक और नकारात्मक 0 को सही तरीके से संभालता है। –

+0

आह, अब मैं देखता हूं, 'INT_MIN' => 'INT_MIN - INT_MIN'। धन्यवाद। – Potatoswatter

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