negative max_num float python python-3.x infinity

python - negative - max_num float inf



¿Cómo hacer un número entero más grande que cualquier otro entero? (7)

Nota: aunque la respuesta aceptada logra el resultado que quería, y la respuesta @ecatmur proporciona una opción más completa, creo que es muy importante enfatizar que mi caso de uso es una mala idea en primer lugar. Esto se explica muy bien en la respuesta de @Jason Orendorff a continuación .

Nota: esta pregunta no es un duplicado de la pregunta sobre sys.maxint . No tiene nada que ver con sys.maxint ; incluso en python 2 donde sys.maxint está disponible, NO representa el entero más grande (vea la respuesta aceptada).

Necesito crear un número entero que sea más grande que cualquier otro número entero, lo que significa un objeto int que devuelve True en comparación con cualquier otro objeto int que use > . Caso de uso: la función de biblioteca espera un número entero, y la única forma fácil de forzar un determinado comportamiento es pasar un número entero muy grande.

En python 2, puedo usar sys.maxint (editar: estaba equivocado). En python 3, math.inf es el equivalente más cercano, pero no puedo convertirlo a int .


Caso de uso: la función de biblioteca espera un número entero, y la única forma fácil de forzar un determinado comportamiento es pasar un número entero muy grande.

Esto suena como una falla en la biblioteca que debería corregirse en su interfaz. Entonces todos sus usuarios se beneficiarían. Que biblioteca es

Crear una subclase int mágica con operadores de comparación anulados podría funcionar para usted. Sin embargo, es frágil; nunca se sabe qué va a hacer la biblioteca con ese objeto. Supongamos que lo convierte en una cadena. ¿Qué debería pasar? Y los datos se usan naturalmente de diferentes maneras a medida que evoluciona una biblioteca; puede actualizar la biblioteca un día para descubrir que su truco ya no funciona.


En Python 3.5, puedes hacer:

import math test = math.inf

Y entonces:

test > 1 test > 10000 test > x

Siempre sera verdad. A menos, por supuesto, como se señaló, x también es infinito o "nan" ("no es un número").

¿Cómo puedo representar un número infinito en Python?

Respondido por @WilHall


Como los enteros de Python no tienen límites, debe hacer esto con una clase personalizada:

import functools @functools.total_ordering class NeverSmaller(object): def __le__(self, other): return False class ReallyMaxInt(NeverSmaller, int): def __repr__(self): return ''ReallyMaxInt()''

Aquí he usado una clase mix-in NeverSmaller lugar de la decoración directa de ReallyMaxInt , porque en Python 3 la acción de functools.total_ordering habría sido impedida por los métodos de pedido existentes heredados de int .

Demostración de uso:

>>> N = ReallyMaxInt() >>> N > sys.maxsize True >>> isinstance(N, int) True >>> sorted([1, N, 0, 9999, sys.maxsize]) [0, 1, 9999, 9223372036854775807, ReallyMaxInt()]

Tenga en cuenta que en python2, sys.maxint + 1 es más grande que sys.maxint , por lo que no puede confiar en eso.

Descargo de responsabilidad : este es un número entero en el sentido OO , no es un número entero en el sentido matemático. En consecuencia, las operaciones aritméticas heredadas de la clase padre int pueden no comportarse con sensatez. Si esto causa algún problema para su caso de uso previsto, entonces se pueden deshabilitar implementando __add__ y amigos para que simplemente se __add__ .


El infinity.Infinity Konsta Vesterinen. Infinity funcionaría ( pypi ), excepto que no hereda de int , pero puede subclasificarlo:

from infinity import Infinity class IntInfinity(Infinity, int): pass assert isinstance(IntInfinity(), int) assert IntInfinity() > 1e100

Otro paquete que implementa valores de "infinito" es Extremes , que fue rescatado del rechazado PEP 326 ; nuevamente, necesitaría subclase de extremes.Max . int e int .


Me parece que esto sería fundamentalmente imposible. Digamos que escribe una función que devuelve este RBI ("int realmente grande"). Si la computadora es capaz de almacenarlo, alguien más podría escribir una función que devuelva el mismo valor. ¿Es tu RBI mayor que sí misma?

Quizás pueda lograr el resultado deseado con algo como la respuesta de @ wim: Cree un objeto que anule los operadores de comparación para hacer que "<" siempre devuelva falso y ">" siempre devuelva verdadero. (No he escrito mucho Python. En la mayoría de los lenguajes orientados a objetos, esto solo funcionaría si la comparación pone su valor primero, IF RBI> x. Si alguien escribe la comparación de otra manera, IF x> RBI, fallará porque el compilador no sabe cómo comparar enteros con una clase definida por el usuario).


No debe heredar de int menos que desee tanto su interfaz como su implementación . (Su implementación es un conjunto de bits que se ensancha automáticamente y representa un número finito. Claramente no quiere eso). Dado que solo desea la interfaz , herede de ABC Integral . Gracias a la respuesta de @ ecatmur, podemos usar el infinity para lidiar con el meollo del infinito (incluida la negación). Así es como podríamos combinar el infinity con la Integral ABC:

import pytest from infinity import Infinity from numbers import Integral class IntegerInfinity(Infinity, Integral): def __and__(self, other): raise NotImplementedError def __ceil__(self): raise NotImplementedError def __floor__(self): raise NotImplementedError def __int__(self): raise NotImplementedError def __invert__(self, other): raise NotImplementedError def __lshift__(self, other): raise NotImplementedError def __mod__(self, other): raise NotImplementedError def __or__(self, other): raise NotImplementedError def __rand__(self, other): raise NotImplementedError def __rlshift__(self, other): raise NotImplementedError def __rmod__(self, other): raise NotImplementedError def __ror__(self, other): raise NotImplementedError def __round__(self): raise NotImplementedError def __rrshift__(self, other): raise NotImplementedError def __rshift__(self, other): raise NotImplementedError def __rxor__(self, other): raise NotImplementedError def __trunc__(self): raise NotImplementedError def __xor__(self, other): raise NotImplementedError def test(): x = IntegerInfinity() assert x > 2 assert not x < 3 assert x >= 5 assert not x <= -10 assert x == x assert not x > x assert not x < x assert x >= x assert x <= x assert -x == -x assert -x <= -x assert -x <= x assert -x < x assert -x < -1000 assert not -x < -x with pytest.raises(Exception): int(x) with pytest.raises(Exception): x | x with pytest.raises(Exception): ceil(x)

Esto se puede ejecutar con pytest para verificar los invariantes requeridos.


Otra forma de hacerlo (muy inspirada por la respuesta de wim) podría ser un objeto que no sea infinito, pero que aumente sobre la marcha según sea necesario.

Esto es lo que tengo en mente:

from functools import wraps class AlwaysBiggerDesc(): ''''''A data descriptor that always returns a value bigger than instance._compare'''''' def __get__(self, instance, owner): try: return instance._compare + 1 except AttributeError: return instance._val def __set__(self, instance, value): try: del instance._compare except AttributeError: pass instance._val = value class BiggerThanYou(int): ''''''A class that behaves like an integer but that increases as needed so as to be bigger than "other" values. Defaults to 1 so that instances are considered to be "truthy" for boolean comparisons.'''''' val = AlwaysBiggerDesc() def __getattribute__(self, name): f = super().__getattribute__(name) try: intf = getattr(int,name) except AttributeError: intf = None if f is intf: @wraps(f) def wrapper(*args): try: self._compare = args[1] except IndexError: self._compare = 0 # Note: 1 will be returned by val descriptor new_bigger = BiggerThanYou() try: new_bigger.val = f(self.val, *args[1:]) except IndexError: new_bigger.val = f(self.val) return new_bigger return wrapper else: return f def __repr__(self): return ''BiggerThanYou()'' def __str__(self): return ''1000...''

Algo como esto podría evitar muchos comportamientos extraños que uno no podría esperar. Tenga en cuenta que con este tipo de enfoque, si dos instancias BiggerThanYou están involucradas en una operación, el LHS se consideraría más grande que el RHS.

EDITAR: actualmente esto no funciona, lo arreglaré más tarde. parece que me está mordiendo la funcionalidad de búsqueda de métodos especiales .