Özet: Bu bir tesadüf değil; Python'un varsayılan CPython uygulamasında _PyHASH_INF
314159 olarak sabit kodlanmıştır ve 2000'de Tim Peters tarafından rasgele bir değer (açıkça π rakamlarından) seçilmiştir .
Değeri, hash(float('inf'))
sayısal türler için yerleşik karma işlevinin sisteme bağlı parametrelerinden biridir ve Python 3'teki gibi de kullanılabilirsys.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 ile de aynı sonuçlar .)
Kod açısından, hash
yerleşik bir işlevdir. Olan işaretçi tarafından verilen fonksiyon bir Python şamandıra nesne üzerinde çağırmaktadır çağrı tp_hash
öznitelik dahili salınım türünde (arasında PyTypeObject PyFloat_Type
), birfloat_hash
işlev, tanımlandığı şekilde return _Py_HashDouble(v->ob_fval)
da, var
if (Py_IS_INFINITY(v))
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
burada _PyHASH_INF
olduğu gibi tanımlanmıştır 314159:
#define _PyHASH_INF 314159
Tarih açısından, 314159
bu bağlamda ilk kez Python kodunda (bunu git bisect
veya ile bulabilirsiniz git log -S 314159 -p
) Ağustos 2000'de Tim Peters tarafından , git deposunda 39dce293 taahhüt edilene eklenmiştircpython
.
Taahhüt mesajı şunu söylüyor:
Http://sourceforge.net/bugs/?func=detailbug&bug_id=111866&group_id=5470 için düzeltme . Bu yanıltıcı bir hataydı - gerçek "hata" bir sonsuzluk hash(x)
olduğunda bir hata dönüş verdi oldu x
. Bunu düzelttim. Alanına yeni Py_IS_INFINITY
makro
eklendi pyport.h
. Float ve karmaşık sayıların karma işlemlerinde artan çoğalmayı azaltmak için kodu yeniden düzenleyerek Trent'in önceki bıçağını mantıklı bir sonuca itti. Bir hata olmasa bile şamandıraların karmaının -1'e dönebileceği son derece nadir bir hata düzeltildi (bir test vakası oluşturmaya çalışırken zaman kaybetmedim, olabileceği koddan açıkça anlaşıldı ). Geliştirilmiş karmaşık karma
artık hash(complex(x, y))
sistematik olarak eşit hash(complex(y, x))
değil.
Özellikle, bu o kodunu yırtık işlemek static long float_hash(PyFloatObject *v)
içinde Objects/floatobject.c
ve sadece yapılan return _Py_HashDouble(v->ob_fval);
ve tanımında long _Py_HashDouble(double v)
içinde Objects/object.c
o satırları ekledi:
if (Py_IS_INFINITY(intpart))
/* can't convert to long int -- arbitrary */
v = v < 0 ? -271828.0 : 314159.0;
Daha önce de belirtildiği gibi, keyfi bir seçimdi. 271.828 ilk birkaç ondalık hane oluştuğunu ileri Not e .
İlgili daha sonraki taahhütler:
hash(float('nan'))
olması0
.