如何在Python中获得10 ** 20 + 10 **-20的确切结果?它给我1e + 20

问题描述 投票:1回答:1

我正在编写代码来求解第二级方程式,并且效果很好。但是,当我输入以下公式时:

x ^ 2 +(10 ^(20)+ 10 ^(-20))+1 = 0

(是,我的输入是10 ** 20 + 10 **(-20)我得到:

x 1 = 0 x 2 = -1e + 20

但是,如果进行数学运算,它将(10 ^(20)+ 10 ^(-20)当作10e + 20,

这是LaTeX格式的公式:

LaTeX formatted formula

几乎是哪个 10 ^ 20,但不是10 ^ 20。如何获得该操作的精确结果,以便可以在x 2中获得方程的精确值?]

我的代码如下:

#===============================Función para obtener los coeficientes===============================

#Se van a anidar dos funciones. Primero la de coeficientes, luego la de la solución de la ecuación.
#Se define una función recursiva para obtener los coeficientes de la ecuación del usuario
def cof():
  #Se determina si el coeficiente a introducir es un número o una cadena de operaciones
  op = input("Si tu coeficiente es un número introduce 1, si es una cadena de operaciones introduce 2")
  #Se compara la entrada del usuario con la opción.
  if op == str(1):
    #Se le solicita el número
    num = input("¿Cuál es tu número?")
    #Se comprueba que efectívamente sea un número
    try:
      #Si la entrada se puede convertir a flotante
      float(num)
      #Se establece el coeficiente como el valor flotante de la entrada
      coef = float(num)
      #Se retorna el valor del coeficiente
      return coef
    #Si no se pudo convertir a flotante...
    except ValueError:
      #Se le informa al usuario del error
      print("No introdujiste un número. Inténtalo de nuevo")
      #Se llama a la función de nuevo
      return cofa()
  #Si el coeficiente es una cadena (como en 10**20 + 10**-20)
  elif op == str(2):
    #La entrada se establece como la entrada del usuario
    entrada = input("Input")
    #Se intenta...
    try:
      #Evaluar la entrada. Si se puede...
      eval(entrada)
      #El coeficiente se establece como la evaluación de la entrada
      coef = eval(entrada)
      #Se regresa el coeficiente
      return coef
    #Si no se pudo establecer como tal...
    except:
      #Se le informa al usuario
      print("No introdujiste una cadena de operaciones válida. Inténtalo de nuevo")
      #Se llama a la función de nuevo
      return cofa()
  #Si no se introdujo ni 1 ni 2 se le informa al usuario
  else:
    #Se imprime el mensaje
    print("No introdujiste n ni c, inténtalo de nuevo")
    #Se llama a la función de nuevo
    return cof()

#===============================Función para resolver la ecuación===============================
#Resuelve la ecuación
def sol_cuadratica():

  #Se pide el valor de a
  print("Introduce el coeficiente para a")
  #Se llama a cof y se guarda el valor para a
  a = cof()
  #Se pide b
  print("Introduce el coeficiente para b")
  #Se llama cof y se guarda b
  b = cof()
  #Se pide c
  print("Introduce el coeficiente para c")
  #Se llama cof y se guarda c
  c = cof()
  #Se le informa al usuario de la ecuación a resolver
  print("Vamos a encontrar las raices de la ecuación {}x² + {}x + {} = 0".format(a, b, c))
  #Se analiza el discriminante
  discriminante = (b**2 - 4*a*c)
  #Si el discriminante es menor que cero, las raices son complejas
  if discriminante < 0:
    #Se le informa al usuario
    print("Las raices son imaginarias. Prueba con otros coeficientes.")
    #Se llama a la función de nuevo
    return sol_cuadratica()
  #Si el discriminante es 0, o mayor que cero, se procede a resolver
  else:   
    #Ecuación para x1
    x1 = (-b + discriminante**(1/2))/(2*a)
    #Ecuación para x2
    x2 = (-b - discriminante**(1/2))/(2*a)
    #Se imprimen los resultados
    print("X1 = " + str(x1))
    print("X2 = " + str(x2))

sol_cuadratica()

忽略评论,我来自一个讲西班牙语的国家。

python math equation exponent largenumber
1个回答
3
投票

机器浮点类型的局限性是为什么在将非常小的数字加到非常大的数字时会忽略该小的数字的原因。

此现象称为吸收或抵消。

使用自定义浮点对象(例如decimal模块),可以达到任何精度(计算速度较慢,因为现在浮点已模拟,并且不再依赖于机器的FPU功能)

decimal module docs

与基于硬件的二进制浮点数不同,十进制模块具有用户可更改的精度(默认为28位),可以与给定问题所需的精度一样大

这可以通过更改以下全局参数decimal.getcontext().prec来实现

import decimal
decimal.getcontext().prec = 41  # min value for the required range

d = decimal.Decimal(10**20)
d2 = decimal.Decimal(10**-20)

现在

>>> d+d2
Decimal('100000000000000000000.00000000000000000001')

如注释中所建议,对于较小的数目,通过在已经存在的decimal对象上使用幂运算符使Decimal模块处理除法更为安全(即使在这里,结果相同):

d2 = decimal.Decimal(10)**-20

因此您可以使用decimal.Decimal对象进行计算,而不是使用本地浮点数。

© www.soinside.com 2019 - 2024. All rights reserved.