【问题标题】:math.log() results in "ValueError: math domain error"math.log() 导致“ValueError:数学域错误”
【发布时间】:2016-01-01 00:26:25
【问题描述】:

这是一个频率到 MIDI 音符的转换器,但我似乎无法让数学运算正常工作。具体来说,使用math.log() 函数。这将在大多数情况下产生 69.0 的输出,但如果我输入任何低于 440 的数字,它通常会输出“ValueError:数学域错误”。我应该如何解决它?

    #d=69+12*log(2)*(f/440)
    #f=2^((d-69)/12)*440
    #d is midi, f is frequency

    import math
    f=raw_input("Type the frequency to be converted to midi: ")
    d=69+(12*math.log(int(f)/440))/(math.log(2))
    print d`

【问题讨论】:

    标签: python math frequency midi


    【解决方案1】:

    这是因为 Python 2 使用整数除法。任何低于 440 的值都将计算为 0,然后传递给 math.log()。

    >>> 500/440
    1
    >>> 440/440
    1
    >>> 439/440
    0
    >>> math.log(0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: math domain error
    

    最简单的方法是通过将这一行放在文件顶部来启用 Python 3 样式,即所谓的真正除法:

    from __future__ import division
    

    现在 Python 2 的行为可能与您预期的一样:

    >>> 439/440
    0.9977272727272727
    >>> math.log(439/440)
    >>> math.log(439/440)
    -0.0022753138371355394
    

    作为替代方案,您可以将除数和/或除数转换为浮点数:

    d=69+(12*math.log(int(f)/440.0))/(math.log(2))
    

    或

    d=69+(12*math.log(float(f)/440))/(math.log(2))
    

    【讨论】:

    • 非常感谢您的解释!它现在可以工作了:D
    【解决方案2】:

    如果是 Python 2,看起来整数除法会使括号中的乘积不精确。尝试除以 440.0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-04
      • 2021-08-04
      • 2020-05-06
      • 1970-01-01
      • 2021-11-10
      相关资源
      最近更新 更多