【问题标题】: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))
【解决方案2】:
如果是 Python 2,看起来整数除法会使括号中的乘积不精确。尝试除以 440.0。