use fractions instead of floats, which are more accurate
- this is a lot slower, but it's not noticeable if you use pypy instead of cpython