Esempio n. 1
0
def _apply_function_in_context(cls, f, args, context):
    """ Apply an MPFR function 'f' to the given arguments 'args', rounding to
    the given context.  Returns a new Mpfr object with precision taken from
    the current context.

    """
    rounding = context.rounding
    bf = mpfr.Mpfr_t.__new__(cls)
    mpfr.mpfr_init2(bf, context.precision)
    args = (bf,) + args + (rounding,)
    ternary = f(*args)
    with _temporary_exponent_bounds(context.emin, context.emax):
        ternary = mpfr.mpfr_check_range(bf, ternary, rounding)
        if context.subnormalize:
            # mpfr_subnormalize doesn't set underflow and
            # subnormal flags, so we do that ourselves.  We choose
            # to set the underflow flag for *all* cases where the
            # 'after rounding' result is smaller than the smallest
            # normal number, even if that result is exact.

            # if bf is zero but ternary is nonzero, the underflow
            # flag will already have been set by mpfr_check_range;
            underflow = (
                mpfr.mpfr_number_p(bf) and
                not mpfr.mpfr_zero_p(bf) and
                mpfr.mpfr_get_exp(bf) < context.precision - 1 + context.emin)
            if underflow:
                mpfr.mpfr_set_underflow()
            ternary = mpfr.mpfr_subnormalize(bf, ternary, rounding)
            if ternary:
                mpfr.mpfr_set_inexflag()
    return bf
Esempio n. 2
0
def _apply_function_in_context(cls, f, args, context):
    """ Apply an MPFR function 'f' to the given arguments 'args', rounding to
    the given context.  Returns a new Mpfr object with precision taken from
    the current context.

    """
    rounding = context.rounding
    bf = mpfr.Mpfr_t.__new__(cls)
    mpfr.mpfr_init2(bf, context.precision)
    args = (bf,) + args + (rounding,)
    ternary = f(*args)
    with _temporary_exponent_bounds(context.emin, context.emax):
        ternary = mpfr.mpfr_check_range(bf, ternary, rounding)
        if context.subnormalize:
            # mpfr_subnormalize doesn't set underflow and
            # subnormal flags, so we do that ourselves.  We choose
            # to set the underflow flag for *all* cases where the
            # 'after rounding' result is smaller than the smallest
            # normal number, even if that result is exact.

            # if bf is zero but ternary is nonzero, the underflow
            # flag will already have been set by mpfr_check_range;
            underflow = (
                mpfr.mpfr_number_p(bf) and
                not mpfr.mpfr_zero_p(bf) and
                mpfr.mpfr_get_exp(bf) < context.precision - 1 + context.emin)
            if underflow:
                mpfr.mpfr_set_underflow()
            ternary = mpfr.mpfr_subnormalize(bf, ternary, rounding)
            if ternary:
                mpfr.mpfr_set_inexflag()
    return bf
Esempio n. 3
0
def _quotient_exponent(x, y):
    """
    Given two positive finite MPFR instances x and y,
    find the exponent of x / y; that is, the unique
    integer e such that 2**(e-1) <= x / y < 2**e.

    """
    assert mpfr.mpfr_regular_p(x)
    assert mpfr.mpfr_regular_p(y)

    # Make copy of x with the exponent of y.
    x2 = mpfr.Mpfr_t()
    mpfr.mpfr_init2(x2, mpfr.mpfr_get_prec(x))
    mpfr.mpfr_set(x2, x, mpfr.MPFR_RNDN)
    mpfr.mpfr_set_exp(x2, mpfr.mpfr_get_exp(y))

    # Compare x2 and y, disregarding the sign.
    extra = mpfr.mpfr_cmpabs(x2, y) >= 0
    return extra + mpfr.mpfr_get_exp(x) - mpfr.mpfr_get_exp(y)