Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

236
Views
¿Por qué el hash del infinito de Python tiene los dígitos de π?

El hash de infinito en Python tiene dígitos que coinciden con pi :

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

¿Es solo una coincidencia o es intencional?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Resumen: No es una coincidencia; _PyHASH_INF está codificado como 314159 en la implementación predeterminada de CPython de Python, y Tim Peters lo eligió como un valor arbitrario (obviamente de los dígitos de π) en 2000 .


El valor de hash(float('inf')) es uno de los parámetros dependientes del sistema de la función hash integrada para tipos numéricos y también está disponible como sys.hash_info.inf en Python 3:

 >>> 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

(Los mismos resultados con PyPy también).


En términos de código, hash es una función integrada. Llamarlo en un objeto flotante de Python invoca la función cuyo puntero está dado por el atributo tp_hash del tipo flotante incorporado ( PyTypeObject PyFloat_Type ), que es la función float_hash , definida como return _Py_HashDouble(v->ob_fval) , que a su vez posee

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

donde _PyHASH_INF se define como 314159:

 #define _PyHASH_INF 314159

En términos de historia, la primera mención de 314159 en este contexto en el código de Python (puede encontrar esto con git bisect o git log -S 314159 -p ) fue agregada por Tim Peters en agosto de 2000, en lo que ahora es commit 39dce293 en el repositorio cpython git.

El mensaje de confirmación dice:

Solución para http://sourceforge.net/bugs/?func=detailbug&bug_id=111866&group_id=5470 . Este fue un error engañoso: el verdadero "error" fue que hash(x) devolvió un error cuando x es un infinito. Arreglado eso. Se agregó una nueva macro Py_IS_INFINITY a pyport.h . Se reorganizó el código para reducir la creciente duplicación en el hash de números flotantes y complejos, lo que llevó la puñalada anterior de Trent a una conclusión lógica. Se corrigió un error extremadamente raro en el que el hashing de flotantes podía devolver -1 incluso si no había un error (no perdió el tiempo tratando de construir un caso de prueba, era simplemente obvio por el código que podría suceder). Hash complejo mejorado para que hash(complex(x, y)) ya no sea sistemáticamente igual a hash(complex(y, x)) .

En particular, en esta confirmación extrajo el código de static long float_hash(PyFloatObject *v) en Objects/floatobject.c y lo hizo return _Py_HashDouble(v->ob_fval); , y en la definición de long _Py_HashDouble(double v) en Objects/object.c agregó las líneas:

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

Entonces, como se mencionó, fue una elección arbitraria. Tenga en cuenta que 271828 se forma a partir de los primeros dígitos decimales de e .

Confirmaciones posteriores relacionadas:

  • Por Mark Dickinson en abril de 2010 ( también ), haciendo que el tipo Decimal se comporte de manera similar

  • Por Mark Dickinson en abril de 2010 ( también ), moviendo este cheque al principio y agregando casos de prueba

  • Por Mark Dickinson en mayo de 2010 como edición 8188 , reescribiendo completamente la función hash asu implementación actual , pero conservando este caso especial, dando a la constante un nombre _PyHASH_INF (también eliminando el 271828, razón por la cual en Python 3 hash(float('-inf')) devuelve -314159 en lugar de -271828 como lo hace en Python 2)

  • Por Raymond Hettinger en enero de 2011 , agregando un ejemplo explícito en "Novedades" para Python 3.2 de sys.hash_info que muestra el valor anterior. (Ver aquí .)

  • Por Stefan Krah en marzo de 2012 modificando el módulo Decimal pero manteniendo este hash.

  • Por Christian Heimes en noviembre de 2013 , movió la definición de _PyHASH_INF de Include/pyport.h a Include/pyhash.h donde ahora reside.

over 4 years ago · Santiago Trujillo Report

0

_PyHASH_INF se define como una constante igual a 314159 .

No puedo encontrar ninguna discusión sobre esto, o comentarios dando una razón. Creo que fue elegido más o menos arbitrariamente. Me imagino que mientras no usen el mismo valor significativo para otros hashes, no debería importar.

over 4 years ago · Santiago Trujillo Report

0

En efecto,

 sys.hash_info.inf

devuelve 314159 . El valor no se genera, está integrado en el código fuente. De hecho,

 hash(float('-inf'))

devuelve -271828 , o aproximadamente -e, en python 2 ( ahora es -314159 ).

El hecho de que los dos números irracionales más famosos de todos los tiempos se utilicen como valores hash hace que sea muy poco probable que sea una coincidencia.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!