# # Reference : # Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to appear) # all_tqs = [] # Generates all possible values of T[q] # Appendix B of Number parsing at a gigabyte per second. # Software: Practice and Experience 2021;51(8):1700–1727. for q in range(-342, -27): power5 = 5**-q z = 0 while (1 << z) < power5: z += 1 b = 2 * z + 2 * 64 c = 2**b // power5 + 1 while c >= (1 << 128): c //= 2 all_tqs.append(c) for q in range(-27, 0): power5 = 5**-q z = 0 while (1 << z) < power5: z += 1 b = z + 127 c = 2**b // power5 + 1 all_tqs.append(c) for q in range(0, 308 + 1): power5 = 5**q while power5 < (1 << 127): power5 *= 2 while power5 >= (1 << 128): power5 //= 2 all_tqs.append(power5) # Returns the continued fraction of numer/denom as a list [a0; a1, a2, ..., an] def continued_fraction(numer, denom): # (look at page numbers in top-left, not PDF page numbers) cf = [] while denom != 0: quot, rem = divmod(numer, denom) cf.append(quot) numer, denom = denom, rem return cf # Given a continued fraction [a0; a1, a2, ..., an], returns # all the convergents of that continued fraction # as pairs of the form (numer, denom), where numer/denom is # a convergent of the continued fraction in simple form. def convergents(cf): p_n_minus_2 = 0 q_n_minus_2 = 1 p_n_minus_1 = 1 q_n_minus_1 = 0 convergents = [] for a_n in cf: p_n = a_n * p_n_minus_1 + p_n_minus_2 q_n = a_n * q_n_minus_1 + q_n_minus_2 convergents.append((p_n, q_n)) p_n_minus_2, q_n_minus_2, p_n_minus_1, q_n_minus_1 = p_n_minus_1, q_n_minus_1, p_n, q_n return convergents # Enumerate through all the convergents of T[q] / 2^137 with denominators < 2^64 found_solution = False for j, tq in enumerate(all_tqs): for _, w in convergents(continued_fraction(tq, 2**137)): if w >= 2**64: break if (tq*w) % 2**137 > 2**137 - 2**64: print(f"SOLUTION: q={j-342} T[q]={tq} w={w}") found_solution = True if not found_solution: print("No solutions!")