def mpfr_to_mpf(f):
    ctx = gmpy2.get_context()
    p = ctx.precision
    # emax = ctx.emax - 1
    # emax = (2 ** (w - 1)) - 1
    # emax + 1 = 2 ** (w - 1)
    # ln2(emax + 1) = w - 1
    # w = ln(emax + 1) + 1
    # w = ln(ctx.emax) + 1
    w = log2(ctx.emax) + 1
    assert w.is_integer()
    w = int(w)
    # w = k - p
    # k = w + p
    k = w + p

    eb = k - p
    sb = p

    rv = MPF(eb, sb)
    if gmpy2.is_nan(f):
        rv.set_nan()
    elif gmpy2.is_infinite(f):
        if gmpy2.sign(f) > 0:
            rv.set_infinite(0)
        else:
            rv.set_infinite(1)
    elif gmpy2.is_zero(f):
        if str(f) == "-0.0":
            rv.set_zero(1)
        elif str(f) == "0.0":
            rv.set_zero(0)
        else:
            assert False
    else:
        a, b = f.as_integer_ratio()
        rv.from_rational(RM_RNE, Rational(int(a), int(b)))
        assert mpf_to_mpfr(rv) == f

    return rv
def build_max_normal(eb, sb, _, sign):
    rv = MPF(eb, sb)
    rv.pack(sign, 2**rv.w - 2, 2**rv.t - 1)
    return rv
def build_one(eb, sb, _, sign):
    rv = MPF(eb, sb)
    rv.from_rational(RM_RNE, Rational(1))
    rv.set_sign_bit(sign)
    return rv
def build_rnd_normal_large(eb, sb, rng, sign):
    rv = MPF(eb, sb)
    rv.pack(sign, rng.random_int(2**(rv.w - 1), 2**rv.w - 2),
            rng.random_int(0, 2**rv.t - 1))
    return rv
def build_rnd_normal_small(eb, sb, rng, sign):
    rv = MPF(eb, sb)
    rv.pack(sign, rng.random_int(1, 2**(rv.w - 1)),
            rng.random_int(0, 2**rv.t - 1))
    return rv
def build_min_normal(eb, sb, _, sign):
    rv = MPF(eb, sb)
    rv.pack(sign, 1, 0)
    return rv
def build_rnd_subnormal(eb, sb, rng, sign):
    rv = MPF(eb, sb)
    rv.pack(sign, 0, rng.random_int(2, 2**rv.t - 2))
    return rv
def build_min_subnormal(eb, sb, _, sign):
    rv = MPF(eb, sb)
    rv.pack(sign, 0, 1)
    return rv
def build_zero(eb, sb, _, sign):
    rv = MPF(eb, sb)
    rv.set_zero(sign)
    return rv
def build_nan(eb, sb, rng):
    rv = MPF(eb, sb)
    rv.pack(rng.random_int(0, 1), 2**rv.w - 1, rng.random_int(1, 2**rv.t - 1))
    return rv
def build_inf(eb, sb, _, sign):
    rv = MPF(eb, sb)
    rv.pack(sign, 2**rv.w - 1, 0)
    return rv