1 #!/usr/bin/env python2 2 3 from math import ceil, floor 4 import sys 5 6 def method2(f, s): 7 r = f / s 8 scale = getscale(r) 9 return scale * r, scale 10 11 def is_integer(x): 12 target = round(x) * 1000 13 #print x, target - 100, floor(x * 1000), target + 100 14 return target - 100 < floor(x * 1000) < target + 100 15 16 def getscale(x): 17 scale = getscale_part(x) 18 if is_integer(scale): 19 return scale 20 return scale * getscale(scale) 21 22 def getscale_part(x): 23 part = x - int(x) 24 if not part: 25 return 1 26 elif part > 0.5: 27 return 1 / (1 - part) 28 else: 29 return 1 / part 30 31 def reduce(m, n, m_limit, n_limit): 32 while m > m_limit and n > n_limit and m > 1 and n > 1: 33 m /= 2 34 n /= 2 35 return m, n 36 37 def show(s, m, n, f_label="f"): 38 print "m =", m 39 print "n =", n 40 print "%s' =" % f_label, s * m / n 41 print "%s' ~=" % f_label, s * round(m) / round(n) 42 43 if len(sys.argv) < 4: 44 f, s = map(float, sys.argv[1:3]) 45 m, n = method2(f, s) 46 m, n = reduce(m, n, 0x200, 0x100000) 47 show(s, m, n) 48 49 else: 50 f, s, i_min, i_max = map(float, sys.argv[1:5]) 51 52 # Constraints: 53 # 54 # i_min < s * m' / di < i_max 55 # i_min / s < m' / di < i_max / s 56 # 57 # f = s * m' / (di * do) 58 # f = (s * m' / di) / do 59 # f * do = s * m' / di 60 # 61 # i_min < f * do < i_max 62 # i_min / f < do < i_max / f 63 # 64 # f = s * m / n 65 # 66 # s * m' / (di * do) = s * m / n 67 # m' / (di * do) = m / n 68 # m' = (m / n) * (di * do) 69 # m' / di = (m / n) * do 70 71 do_min = ceil(i_min / f) 72 do_max = floor(i_max / f) 73 74 do = do_min 75 76 print do_min, "<= do <=", do_max 77 78 while do <= do_max: 79 do0 = int(do ** 0.5) 80 do1 = int(do / do0) 81 if do0 * do1 == int(do): 82 i = do * f 83 m, n = method2(i, s) 84 m, n = reduce(m, n, 0x3f, 0x3f) 85 if m <= 0x3f and n <= 0x3f: 86 show(i, m, n, "i") 87 print "do =", do 88 print "do0 =", do0 89 print "do1 =", do1 90 print "f' =", s * m / (n * do) 91 print "f' ~=", s * round(m) / (round(n) * round(do)) 92 break 93 else: 94 print "Ignored: m =", m, "n =", n, "do0 =", do0, "do1 =", do1 95 do += 1 96 97 # vim: tabstop=4 expandtab shiftwidth=4