सारांश: यह एक संयोग नहीं है; पायथन के डिफ़ॉल्ट CPython कार्यान्वयन में _PyHASH_INF
314159 के रूप में हार्डकोड किया गया है, और 2000 में टिम पीटर्स द्वारा एक मनमाना मूल्य (स्पष्ट रूप से π के अंकों से) के रूप में चुना गया था ।
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
एक अंतर्निहित फ़ंक्शन है। एक अजगर नाव वस्तु पर यह कॉलिंग समारोह जिसका सूचक द्वारा दिया जाता है invokes tp_hash
विशेषता में निर्मित नाव प्रकार (की PyTypeObject PyFloat_Type
) है, जो हैfloat_hash
समारोह, परिभाषित के रूप में return _Py_HashDouble(v->ob_fval)
, जो बारी में है
if (Py_IS_INFINITY(v))
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
जहां 314159 के रूप_PyHASH_INF
में परिभाषित किया गया है:
#define _PyHASH_INF 314159
इतिहास के 314159
संदर्भ में, पायथन कोड में इस संदर्भ में पहला उल्लेख (आप इस के साथ git bisect
या पा सकते हैं git log -S 314159 -p
) टिम पीटर्स द्वारा अगस्त 2000 में जोड़ा गया था , जो अब गिट रिपॉजिटरी में 39dce293 प्रतिबद्ध cpython
है।
प्रतिबद्ध संदेश कहता है:
Http://sourceforge.net/bugs/?func=detailbug&bug_id=111866&group_id=5470 के लिए ठीक करें । यह एक भ्रामक बग था - सही "बग" यह था कि एक अनन्तता hash(x)
होने पर एक त्रुटि वापसी दी गई थी x
। तय किया कि में नया Py_IS_INFINITY
मैक्रो
जोड़ा गया pyport.h
। फ्लोट और जटिल संख्या के हैशिंग में बढ़ते दोहराव को कम करने के लिए कोडित कोड, एक तार्किक निष्कर्ष पर ट्रेंट के पहले छुरा को धक्का देता है। बहुत हद तक दुर्लभ बग जहां फ्लोट्स के हैशिंग वापस आ सकते हैं, भले ही कोई त्रुटि न हो (परीक्षण के समय का निर्माण करने की कोशिश में समय बर्बाद न हो, यह कोड से बस स्पष्ट था कि ऐसा हो सकता है)। बेहतर जटिल हैश ताकि
अब hash(complex(x, y))
व्यवस्थित रूप से बराबर न हो hash(complex(y, x))
।
विशेष रूप से, इस में प्रतिबद्ध वह के कोड बाहर फट static long float_hash(PyFloatObject *v)
में Objects/floatobject.c
और यह सिर्फ बनाया return _Py_HashDouble(v->ob_fval);
, और की परिभाषा में long _Py_HashDouble(double v)
में Objects/object.c
वह लाइनों कहा:
if (Py_IS_INFINITY(intpart))
/* can't convert to long int -- arbitrary */
v = v < 0 ? -271828.0 : 314159.0;
जैसा कि उल्लेख किया गया है, यह एक मनमाना विकल्प था। ध्यान दें कि 271828 ई के पहले कुछ दशमलव अंकों से बनता है ।
संबंधित बाद में करता है:
hash(float('nan'))
जा रहा है0
।