python - क्यों अनंत के पायथन हैश's के अंक है?




math hash (2)

वास्तव में,

sys.hash_info.inf

रिटर्न 314159 । मान उत्पन्न नहीं हुआ है, यह स्रोत कोड में बनाया गया है। असल में,

hash(float('-inf'))

रिटर्न -271828 , या लगभग-ई, अजगर 2 में ( यह अब -314159 है )।

तथ्य यह है कि सभी समय के दो सबसे प्रसिद्ध तर्कहीन संख्याओं का उपयोग हैश मूल्यों के रूप में किया जाता है, यह एक संयोग होने की संभावना को बहुत कम कर देता है।

पायथन में अनंत के हैश में अंक मिलान pi :

>>> inf = float('inf')
>>> hash(inf)
314159
>>> int(math.pi*1e5)
314159

क्या यह महज एक संयोग है या यह जानबूझकर किया गया है?


सारांश: यह एक संयोग नहीं है; _PyHASH_INF पायथन के डिफ़ॉल्ट CPython कार्यान्वयन में 314159 के रूप में हार्डकोड किया गया है, और 2000 में टिम पीटर्स द्वारा एक मनमाना मूल्य (स्पष्ट रूप से the के अंकों से) के रूप में चुना गया था।

hash(float('inf')) का मान संख्यात्मक प्रकारों के लिए अंतर्निहित हैश फ़ंक्शन के सिस्टम-निर्भर मापदंडों में से एक है, और पायथन 3 में sys.hash_info.inf रूप में भी उपलब्ध है :

>>> import sys
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003, algorithm='siphash24', hash_bits=64, seed_bits=128, cutoff=0)
>>> sys.hash_info.inf
314159

( PyPy के साथ भी समान परिणाम।)

कोड के संदर्भ में, hash एक अंतर्निहित फ़ंक्शन है। इसे पायथन फ्लोट ऑब्जेक्ट पर कॉल करना उस फ़ंक्शन को आमंत्रित करता है जिसका पॉइंटर अंतर्निहित फ्लोट प्रकार के tp_hash विशेषता ( PyTypeObject PyFloat_Type ) द्वारा दिया जाता है, जो is फ्लोट- float_hash फ़ंक्शन है, defined return _Py_HashDouble(v->ob_fval) रूप return _Py_HashDouble(v->ob_fval) defined किया गया है। has

    if (Py_IS_INFINITY(v))
        return v > 0 ? _PyHASH_INF : -_PyHASH_INF;

जहां _PyHASH_INF को _PyHASH_INF के रूप में परिभाषित किया गया है:

#define _PyHASH_INF 314159

इतिहास के संदर्भ में, पायथन कोड में इस संदर्भ में 314159 का पहला उल्लेख (आप git log -S 314159 -p या git log -S 314159 -p साथ यह पा सकते हैं) टिम पीटर्स द्वारा अगस्त 2000 में जोड़ा गया था, जिसमें अब github.com/python/cpython/commit/… प्रतिबद्ध है। cpython git रिपॉजिटरी।

प्रतिबद्ध संदेश कहता है:

http://sourceforge.net/bugs/?func=detailbug&bug_id=111866&group_id=5470 लिए ठीक करें। यह एक भ्रामक बग था - सही "बग" यह था कि hash(x) ने एक त्रुटि रिटर्न दिया जब x एक अनंत है। तय किया कि Py_IS_INFINITY नया Py_IS_INFINITY मैक्रो जोड़ा गया। फ्लोट और जटिल संख्या के हैशिंग में बढ़ते दोहराव को कम करने के लिए पुन: व्यवस्थित कोड, ट्रेंट के पहले स्टैब को एक तार्किक निष्कर्ष पर धकेल देता है। बहुत हद तक दुर्लभ बग जहां फ्लोट्स के हैशिंग वापस आ सकते हैं, भले ही कोई त्रुटि नहीं थी (परीक्षण के मामले का निर्माण करने की कोशिश में समय बर्बाद नहीं हुआ, यह कोड से स्पष्ट था कि ऐसा हो सकता है)। बेहतर जटिल हैश ताकि hash(complex(x, y)) अब व्यवस्थित रूप से बराबर hash(complex(y, x)) नहीं करता है।

विशेष रूप से, इस प्रतिबद्ध में उन्होंने Objects/floatobject.c में static long float_hash(PyFloatObject *v) के कोड को काट दिया और इसे सिर्फ return _Py_HashDouble(v->ob_fval); , और Objects/object.c long _Py_HashDouble(double v) में long _Py_HashDouble(double v) की परिभाषा में उन्होंने लाइनें long _Py_HashDouble(double v) :

        if (Py_IS_INFINITY(intpart))
            /* can't convert to long int -- arbitrary */
            v = v < 0 ? -271828.0 : 314159.0;

जैसा कि उल्लेख किया गया है, यह एक मनमाना विकल्प था। ध्यान दें कि 271828 e के पहले कुछ दशमलव अंकों से बनता है।

बाद में संबंधित संबंधित:





pi