【问题标题】:float division by zero Python浮点除以零 Python
【发布时间】:2020-02-20 16:06:35
【问题描述】:

我试图将一个数字除以一个很小的数字。 “q”始终是介于 0 和 1 之间的浮点数,当 n 超过 1000 时,输出显示“浮点除以零”,因为它将小数舍入为零。我尝试过使用 Decimal 但仍然无法正常工作

#Librerías
import numpy as np
import matplotlib.pyplot as plt
from decimal import Decimal

#Datos
p = float(input("Introduzca probabilidad de error de bit: "))
while p < 0 or p > 1:
    p = float(input("Introduzca probabilidad de error de bit: "))
n = int(input("Introduzca número de bits: "))
while n < 0:
    n = int(input("Introduzca número de bits: "))

#Cálculos
q = 1-p
pexito = (q**n)
intentos = 1/pexito
print()
print("El número medio de intentos es:",intentos)
print()
print("La probabilidad de transmitir correctamente",n,"bits es:",pexito)



ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-10-606e023fc7ec> in <module>
     15 q = 1-p
     16 pexito = (q**n)
---> 17 intentos = 1/pexito
     18 print()
     19 print("El número medio de intentos es:",intentos)

ZeroDivisionError: float division by zero

【问题讨论】:

  • 我不确定你在期待什么。如果你除以一个非常小的数字,你会得到一个非常大的数字,直到一个点。对于 64 位,限制在 1e-3231e+308 附近。如果您需要1e300“尝试”(intentos)或1e500,这真的很重要吗?从功能上讲,此时概率为零,因此不妨进行无限尝试。只需将pexito == 0.0 作为特例处理即可。

标签: python decimal division


【解决方案1】:

尝试增加your precision:

from decimal import Decimal, getcontext

getcontext().prec = 2*n

a = Decimal(a)
b = Decimal(b)
c = a/b

【讨论】:

  • 这在p = Decimal(0.001) 时不起作用,因为p ** n 需要多于2*n 的小数位才能不为零。
  • 2*n 只是一个例子,估计作者会弄清楚大致的想法。
  • 是的,0.001 只是一个例子。无论您添加多少小数位,都不一定足够,因为 p 可能足够小,以至于 p ** n 仍然为零。您必须使小数位数取决于1/p
【解决方案2】:

您可以使用标准库中的 Fraction 类对分数进行精确算术:

>>> from fractions import Fraction
>>> n = 2000
>>> p = Fraction(1, 2)
>>> result = p ** n
>>> 1 / result
Fraction(114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029376, 1)

Fraction 构造函数还接受十进制格式的字符串,例如 '0.5' 或精确的分数,例如 '1/2',因此您可以使用 p = Fraction(input(...)) 而不是 float(input(...))

请注意,如果结果实际上为零(当p 本身为零时会发生这种情况),这仍然会给您一个ZeroDivisionError

【讨论】:

    【解决方案3】:

    尝试在第 17 行将 pexito 转换为浮点数

        intentos = 1/float(pexito)
    

    【讨论】:

    • 这与其他人 5 分钟前发布的错误一样。
    【解决方案4】:

    因为n 是一个整数。所以

    q = 1-p
    pexito = (q**n)
    

    pexito = (q**n) 也是一个整数。这就是引发除以零异常的原因。如果您想让intentos = 1/pexito 成为浮点除法,那么只需将其写为:

    intentos = 1/float(pexito)
    

    但请记住,float64 位,decimal128 位。 如果n 是一个很大的数字,则使用doubledecimal 而不是float。 它将解决除以零的问题。

    更新:

    这是正确的代码:

    #Librerías
    import numpy as np
    import matplotlib.pyplot as plt
    from decimal import Decimal
    
    #Datos
    p = float(input("Introduzca probabilidad de error de bit: "))
    while p < 0 or p > 1:
        p = float(input("Introduzca probabilidad de error de bit: "))
    n = int(input("Introduzca número de bits: "))
    while n < 0:
        n = int(input("Introduzca número de bits: "))
    
    #Cálculos
    q = 1-p
    pexito = (q**n)
    intentos = 1/float(pexito)
    print()
    print("El número medio de intentos es:",intentos)
    print()
    print("La probabilidad de transmitir correctamente",n,"bits es:",pexito)
    

    只需检查它的值 0.5 和 5。它工作得很好!但是对于大数字,您必须计算它所需的位数并相应地使用关键字。谢谢

    【讨论】:

    • 您可以通过使用 REPL 来验证这两件事是否有误 - 尝试编写 0.5 ** 5,您会看到它是一个浮点数,即使 5 是一个整数。然后尝试写1 / float(0),你会看到它仍然给出ZeroDivisionError。请在发帖前进行测试。
    • 让我看看你运行这个脚本后输入的值是多少?
    • 所以用0.5 ** 2000试试吧。
    • Python 中甚至没有 double 类型; float 类型是双精度 IEEE 754 浮点数(即 float 是 64 位,而不是 32 位),并且 Python 没有本机单精度浮点数。我认为这里的问题是你试图写一个你实际上不知道答案的问题的答案。
    • 感谢您的纠正,您是对的,python 中没有双精度。实际上pythonfloat是64位的,相当于C/C++的double
    猜你喜欢
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 2012-03-10
    相关资源
    最近更新 更多