繁体   English   中英

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

[英]How can I get the exact result of 10**20 + 10**-20 in Python? It gives me 1e+20

我正在编写一个代码来解决二年级方程,它工作得很好。 但是,当我输入以下等式时:

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 格式化公式

几乎是 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()

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

机器浮点类型的限制是为什么在将一个非常小的数字添加到一个非常大的数字时,小数字只是被忽略的原因。

这种现象称为吸收或抵消。

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

十进制模块文档

与基于硬件的二进制浮点不同,十进制模块具有用户可更改的精度(默认为 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 object 上使用幂运算符来处理除法更安全(即使在这里,结果是相同的):

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM