Spencer Churchill - 5 years ago 288

Python Question

This is a frequency to midi note converter, but I cant seem to get the math to work properly... specifically with the math.log function. This will produce an output of 69.0 most of the time... but it usually outputs "ValueError: math domain error" if I input any number below 440. How should I fix it?

`#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`

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

This is because Python 2 uses integer division. Anything below 440 will evaluate to 0 which is then passed to `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
```

The easiest way is to enable Python 3 style so called true division by placing this line at the top of your file:

```
from __future__ import division
```

Now Python 2 will behave as you might have expected:

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

As alternatives, you can convert the dividend and/or divisor to a float:

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

or

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

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**