示例#1
0
文件: rcomplex.py 项目: Darriall/pypy
def c_sinh(x, y):
    # special treatment for sinh(+/-inf + iy) if y is finite and nonzero
    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            else:
                real = -copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            r = (real, imag)
        else:
            r = sinh_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/- infinity and x is not
        # a NaN
        if isinf(y) and not isnan(x):
            raise ValueError("math domain error")
        return r

    if fabs(x) > CM_LOG_LARGE_DOUBLE:
        x_minus_one = x - copysign(1., x)
        real = math.cos(y) * math.sinh(x_minus_one) * math.e
        imag = math.sin(y) * math.cosh(x_minus_one) * math.e
    else:
        real = math.cos(y) * math.sinh(x)
        imag = math.sin(y) * math.cosh(x)
    if isinf(real) or isinf(imag):
        raise OverflowError("math range error")
    return real, imag
示例#2
0
文件: rcomplex.py 项目: Darriall/pypy
def c_exp(x, y):
    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            else:
                real = copysign(0., math.cos(y))
                imag = copysign(0., math.sin(y))
            r = (real, imag)
        else:
            r = exp_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/- infinity and x is not
        # a NaN and not -infinity
        if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)):
            raise ValueError("math domain error")
        return r

    if x > CM_LOG_LARGE_DOUBLE:
        l = math.exp(x-1.)
        real = l * math.cos(y) * math.e
        imag = l * math.sin(y) * math.e
    else:
        l = math.exp(x)
        real = l * math.cos(y)
        imag = l * math.sin(y)
    if isinf(real) or isinf(imag):
        raise OverflowError("math range error")
    return real, imag
示例#3
0
文件: rcomplex.py 项目: Darriall/pypy
def c_cosh(x, y):
    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            else:
                real = copysign(INF, math.cos(y))
                imag = -copysign(INF, math.sin(y))
            r = (real, imag)
        else:
            r = cosh_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/- infinity and x is not
        # a NaN
        if isinf(y) and not isnan(x):
            raise ValueError("math domain error")
        return r

    if fabs(x) > CM_LOG_LARGE_DOUBLE:
        # deal correctly with cases where cosh(x) overflows but
        # cosh(z) does not.
        x_minus_one = x - copysign(1., x)
        real = math.cos(y) * math.cosh(x_minus_one) * math.e
        imag = math.sin(y) * math.sinh(x_minus_one) * math.e
    else:
        real = math.cos(y) * math.cosh(x)
        imag = math.sin(y) * math.sinh(x)
    if isinf(real) or isinf(imag):
        raise OverflowError("math range error")
    return real, imag
示例#4
0
文件: rcomplex.py 项目: Darriall/pypy
def c_atanh(x, y):
    if not isfinite(x) or not isfinite(y):
        return atanh_special_values[special_type(x)][special_type(y)]

    # Reduce to case where x >= 0., using atanh(z) = -atanh(-z).
    if x < 0.:
        return c_neg(*c_atanh(*c_neg(x, y)))

    ay = fabs(y)
    if x > CM_SQRT_LARGE_DOUBLE or ay > CM_SQRT_LARGE_DOUBLE:
        # if abs(z) is large then we use the approximation
        # atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign
        # of y
        h = math.hypot(x/2., y/2.)   # safe from overflow
        real = x/4./h/h
        # the two negations in the next line cancel each other out
        # except when working with unsigned zeros: they're there to
        # ensure that the branch cut has the correct continuity on
        # systems that don't support signed zeros
        imag = -copysign(math.pi/2., -y)
    elif x == 1. and ay < CM_SQRT_DBL_MIN:
        # C99 standard says:  atanh(1+/-0.) should be inf +/- 0i
        if ay == 0.:
            raise ValueError("math domain error")
            #real = INF
            #imag = y
        else:
            real = -math.log(math.sqrt(ay)/math.sqrt(math.hypot(ay, 2.)))
            imag = copysign(math.atan2(2., -ay) / 2, y)
    else:
        real = log1p(4.*x/((1-x)*(1-x) + ay*ay))/4.
        imag = -math.atan2(-2.*y, (1-x)*(1+x) - ay*ay) / 2.
    return (real, imag)
示例#5
0
文件: rcomplex.py 项目: sota/pypy-old
def c_rect(r, phi):
    if not isfinite(r) or not isfinite(phi):
        # if r is +/-infinity and phi is finite but nonzero then
        # result is (+-INF +-INF i), but we need to compute cos(phi)
        # and sin(phi) to figure out the signs.
        if isinf(r) and isfinite(phi) and phi != 0.:
            if r > 0:
                real = copysign(INF, math.cos(phi))
                imag = copysign(INF, math.sin(phi))
            else:
                real = -copysign(INF, math.cos(phi))
                imag = -copysign(INF, math.sin(phi))
            z = (real, imag)
        else:
            z = rect_special_values[special_type(r)][special_type(phi)]

        # need to raise ValueError if r is a nonzero number and phi
        # is infinite
        if r != 0. and not isnan(r) and isinf(phi):
            raise ValueError("math domain error")
        return z

    real = r * math.cos(phi)
    imag = r * math.sin(phi)
    return real, imag
示例#6
0
文件: rcomplex.py 项目: sota/pypy-old
def c_sinh(x, y):
    # special treatment for sinh(+/-inf + iy) if y is finite and nonzero
    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            else:
                real = -copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            r = (real, imag)
        else:
            r = sinh_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/- infinity and x is not
        # a NaN
        if isinf(y) and not isnan(x):
            raise ValueError("math domain error")
        return r

    if fabs(x) > CM_LOG_LARGE_DOUBLE:
        x_minus_one = x - copysign(1., x)
        real = math.cos(y) * math.sinh(x_minus_one) * math.e
        imag = math.sin(y) * math.cosh(x_minus_one) * math.e
    else:
        real = math.cos(y) * math.sinh(x)
        imag = math.sin(y) * math.cosh(x)
    if isinf(real) or isinf(imag):
        raise OverflowError("math range error")
    return real, imag
示例#7
0
文件: rcomplex.py 项目: sota/pypy-old
def c_atanh(x, y):
    if not isfinite(x) or not isfinite(y):
        return atanh_special_values[special_type(x)][special_type(y)]

    # Reduce to case where x >= 0., using atanh(z) = -atanh(-z).
    if x < 0.:
        return c_neg(*c_atanh(*c_neg(x, y)))

    ay = fabs(y)
    if x > CM_SQRT_LARGE_DOUBLE or ay > CM_SQRT_LARGE_DOUBLE:
        # if abs(z) is large then we use the approximation
        # atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign
        # of y
        h = math.hypot(x / 2., y / 2.)  # safe from overflow
        real = x / 4. / h / h
        # the two negations in the next line cancel each other out
        # except when working with unsigned zeros: they're there to
        # ensure that the branch cut has the correct continuity on
        # systems that don't support signed zeros
        imag = -copysign(math.pi / 2., -y)
    elif x == 1. and ay < CM_SQRT_DBL_MIN:
        # C99 standard says:  atanh(1+/-0.) should be inf +/- 0i
        if ay == 0.:
            raise ValueError("math domain error")
            #real = INF
            #imag = y
        else:
            real = -math.log(math.sqrt(ay) / math.sqrt(math.hypot(ay, 2.)))
            imag = copysign(math.atan2(2., -ay) / 2, y)
    else:
        real = log1p(4. * x / ((1 - x) * (1 - x) + ay * ay)) / 4.
        imag = -math.atan2(-2. * y, (1 - x) * (1 + x) - ay * ay) / 2.
    return (real, imag)
示例#8
0
文件: rcomplex.py 项目: sota/pypy-old
def c_exp(x, y):
    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            else:
                real = copysign(0., math.cos(y))
                imag = copysign(0., math.sin(y))
            r = (real, imag)
        else:
            r = exp_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/- infinity and x is not
        # a NaN and not -infinity
        if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)):
            raise ValueError("math domain error")
        return r

    if x > CM_LOG_LARGE_DOUBLE:
        l = math.exp(x - 1.)
        real = l * math.cos(y) * math.e
        imag = l * math.sin(y) * math.e
    else:
        l = math.exp(x)
        real = l * math.cos(y)
        imag = l * math.sin(y)
    if isinf(real) or isinf(imag):
        raise OverflowError("math range error")
    return real, imag
示例#9
0
文件: rcomplex.py 项目: Darriall/pypy
def c_rect(r, phi):
    if not isfinite(r) or not isfinite(phi):
        # if r is +/-infinity and phi is finite but nonzero then
        # result is (+-INF +-INF i), but we need to compute cos(phi)
        # and sin(phi) to figure out the signs.
        if isinf(r) and isfinite(phi) and phi != 0.:
            if r > 0:
                real = copysign(INF, math.cos(phi))
                imag = copysign(INF, math.sin(phi))
            else:
                real = -copysign(INF, math.cos(phi))
                imag = -copysign(INF, math.sin(phi))
            z = (real, imag)
        else:
            z = rect_special_values[special_type(r)][special_type(phi)]

        # need to raise ValueError if r is a nonzero number and phi
        # is infinite
        if r != 0. and not isnan(r) and isinf(phi):
            raise ValueError("math domain error")
        return z

    real = r * math.cos(phi)
    imag = r * math.sin(phi)
    return real, imag
示例#10
0
文件: rcomplex.py 项目: sota/pypy-old
def c_cosh(x, y):
    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = copysign(INF, math.cos(y))
                imag = copysign(INF, math.sin(y))
            else:
                real = copysign(INF, math.cos(y))
                imag = -copysign(INF, math.sin(y))
            r = (real, imag)
        else:
            r = cosh_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/- infinity and x is not
        # a NaN
        if isinf(y) and not isnan(x):
            raise ValueError("math domain error")
        return r

    if fabs(x) > CM_LOG_LARGE_DOUBLE:
        # deal correctly with cases where cosh(x) overflows but
        # cosh(z) does not.
        x_minus_one = x - copysign(1., x)
        real = math.cos(y) * math.cosh(x_minus_one) * math.e
        imag = math.sin(y) * math.sinh(x_minus_one) * math.e
    else:
        real = math.cos(y) * math.cosh(x)
        imag = math.sin(y) * math.sinh(x)
    if isinf(real) or isinf(imag):
        raise OverflowError("math range error")
    return real, imag
示例#11
0
文件: rcomplex.py 项目: sota/pypy-old
def c_log(x, y):
    # The usual formula for the real part is log(hypot(z.real, z.imag)).
    # There are four situations where this formula is potentially
    # problematic:
    #
    # (1) the absolute value of z is subnormal.  Then hypot is subnormal,
    # so has fewer than the usual number of bits of accuracy, hence may
    # have large relative error.  This then gives a large absolute error
    # in the log.  This can be solved by rescaling z by a suitable power
    # of 2.
    #
    # (2) the absolute value of z is greater than DBL_MAX (e.g. when both
    # z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX)
    # Again, rescaling solves this.
    #
    # (3) the absolute value of z is close to 1.  In this case it's
    # difficult to achieve good accuracy, at least in part because a
    # change of 1ulp in the real or imaginary part of z can result in a
    # change of billions of ulps in the correctly rounded answer.
    #
    # (4) z = 0.  The simplest thing to do here is to call the
    # floating-point log with an argument of 0, and let its behaviour
    # (returning -infinity, signaling a floating-point exception, setting
    # errno, or whatever) determine that of c_log.  So the usual formula
    # is fine here.

    # XXX the following two lines seem unnecessary at least on Linux;
    # the tests pass fine without them
    if not isfinite(x) or not isfinite(y):
        return log_special_values[special_type(x)][special_type(y)]

    ax = fabs(x)
    ay = fabs(y)

    if ax > CM_LARGE_DOUBLE or ay > CM_LARGE_DOUBLE:
        real = math.log(math.hypot(ax / 2., ay / 2.)) + M_LN2
    elif ax < DBL_MIN and ay < DBL_MIN:
        if ax > 0. or ay > 0.:
            # catch cases where hypot(ax, ay) is subnormal
            real = math.log(
                math.hypot(math.ldexp(ax, DBL_MANT_DIG),
                           math.ldexp(ay, DBL_MANT_DIG)))
            real -= DBL_MANT_DIG * M_LN2
        else:
            # log(+/-0. +/- 0i)
            raise ValueError("math domain error")
            #real = -INF
            #imag = atan2(y, x)
    else:
        h = math.hypot(ax, ay)
        if 0.71 <= h and h <= 1.73:
            am = max(ax, ay)
            an = min(ax, ay)
            real = log1p((am - 1) * (am + 1) + an * an) / 2.
        else:
            real = math.log(h)
    imag = math.atan2(y, x)
    return (real, imag)
示例#12
0
文件: rcomplex.py 项目: Darriall/pypy
def c_log(x, y):
    # The usual formula for the real part is log(hypot(z.real, z.imag)).
    # There are four situations where this formula is potentially
    # problematic:
    #
    # (1) the absolute value of z is subnormal.  Then hypot is subnormal,
    # so has fewer than the usual number of bits of accuracy, hence may
    # have large relative error.  This then gives a large absolute error
    # in the log.  This can be solved by rescaling z by a suitable power
    # of 2.
    #
    # (2) the absolute value of z is greater than DBL_MAX (e.g. when both
    # z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX)
    # Again, rescaling solves this.
    #
    # (3) the absolute value of z is close to 1.  In this case it's
    # difficult to achieve good accuracy, at least in part because a
    # change of 1ulp in the real or imaginary part of z can result in a
    # change of billions of ulps in the correctly rounded answer.
    #
    # (4) z = 0.  The simplest thing to do here is to call the
    # floating-point log with an argument of 0, and let its behaviour
    # (returning -infinity, signaling a floating-point exception, setting
    # errno, or whatever) determine that of c_log.  So the usual formula
    # is fine here.

    # XXX the following two lines seem unnecessary at least on Linux;
    # the tests pass fine without them
    if not isfinite(x) or not isfinite(y):
        return log_special_values[special_type(x)][special_type(y)]

    ax = fabs(x)
    ay = fabs(y)

    if ax > CM_LARGE_DOUBLE or ay > CM_LARGE_DOUBLE:
        real = math.log(math.hypot(ax/2., ay/2.)) + M_LN2
    elif ax < DBL_MIN and ay < DBL_MIN:
        if ax > 0. or ay > 0.:
            # catch cases where hypot(ax, ay) is subnormal
            real = math.log(math.hypot(math.ldexp(ax, DBL_MANT_DIG),
                                       math.ldexp(ay, DBL_MANT_DIG)))
            real -= DBL_MANT_DIG*M_LN2
        else:
            # log(+/-0. +/- 0i)
            raise ValueError("math domain error")
            #real = -INF
            #imag = atan2(y, x)
    else:
        h = math.hypot(ax, ay)
        if 0.71 <= h and h <= 1.73:
            am = max(ax, ay)
            an = min(ax, ay)
            real = log1p((am-1)*(am+1) + an*an) / 2.
        else:
            real = math.log(h)
    imag = math.atan2(y, x)
    return (real, imag)
示例#13
0
def ll_math_pow(x, y):
    # deal directly with IEEE specials, to cope with problems on various
    # platforms whose semantics don't exactly match C99

    if isnan(y):
        if x == 1.0:
            return 1.0   # 1**Nan = 1
        return y

    if not isfinite(x):
        if isnan(x):
            if y == 0.0:
                return 1.0   # NaN**0 = 1
            return x
        else:   # isinf(x)
            odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0
            if y > 0.0:
                if odd_y:
                    return x
                return math_fabs(x)
            elif y == 0.0:
                return 1.0
            else:   # y < 0.0
                if odd_y:
                    return math_copysign(0.0, x)
                return 0.0

    if isinf(y):
        if math_fabs(x) == 1.0:
            return 1.0
        elif y > 0.0 and math_fabs(x) > 1.0:
            return y
        elif y < 0.0 and math_fabs(x) < 1.0:
            if x == 0.0:
                raise ValueError("0**-inf: divide by zero")
            return -y    # result is +inf
        else:
            return 0.0

    _error_reset()
    r = math_pow(x, y)
    errno = rposix.get_errno()
    if not isfinite(r):
        if isnan(r):
            # a NaN result should arise only from (-ve)**(finite non-integer)
            errno = EDOM
        else:   # isinf(r)
            # an infinite result here arises either from:
            # (A) (+/-0.)**negative (-> divide-by-zero)
            # (B) overflow of x**y with x and y finite
            if x == 0.0:
                errno = EDOM
            else:
                errno = ERANGE
    if errno:
        _likely_raise(errno, r)
    return r
示例#14
0
文件: ll_math.py 项目: soIu/rpython
def ll_math_pow(x, y):
    # deal directly with IEEE specials, to cope with problems on various
    # platforms whose semantics don't exactly match C99

    if math.isnan(y):
        if x == 1.0:
            return 1.0  # 1**Nan = 1
        return y

    if not isfinite(x):
        if math.isnan(x):
            if y == 0.0:
                return 1.0  # NaN**0 = 1
            return x
        else:  # isinf(x)
            odd_y = not math.isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0
            if y > 0.0:
                if odd_y:
                    return x
                return math_fabs(x)
            elif y == 0.0:
                return 1.0
            else:  # y < 0.0
                if odd_y:
                    return math_copysign(0.0, x)
                return 0.0

    if math.isinf(y):
        if math_fabs(x) == 1.0:
            return 1.0
        elif y > 0.0 and math_fabs(x) > 1.0:
            return y
        elif y < 0.0 and math_fabs(x) < 1.0:
            if x == 0.0:
                raise ValueError("0**-inf: divide by zero")
            return -y  # result is +inf
        else:
            return 0.0

    r = math_pow(x, y)
    errno = rposix.get_saved_errno()
    if not isfinite(r):
        if math.isnan(r):
            # a NaN result should arise only from (-ve)**(finite non-integer)
            errno = EDOM
        else:  # isinf(r)
            # an infinite result here arises either from:
            # (A) (+/-0.)**negative (-> divide-by-zero)
            # (B) overflow of x**y with x and y finite
            if x == 0.0:
                errno = EDOM
            else:
                errno = ERANGE
    if errno:
        _likely_raise(errno, r)
    return r
示例#15
0
文件: rcomplex.py 项目: Darriall/pypy
def c_sqrt(x, y):
    '''
    Method: use symmetries to reduce to the case when x = z.real and y
    = z.imag are nonnegative.  Then the real part of the result is
    given by
    
      s = sqrt((x + hypot(x, y))/2)
    
    and the imaginary part is
    
      d = (y/2)/s
    
    If either x or y is very large then there's a risk of overflow in
    computation of the expression x + hypot(x, y).  We can avoid this
    by rewriting the formula for s as:
    
      s = 2*sqrt(x/8 + hypot(x/8, y/8))
    
    This costs us two extra multiplications/divisions, but avoids the
    overhead of checking for x and y large.
    
    If both x and y are subnormal then hypot(x, y) may also be
    subnormal, so will lack full precision.  We solve this by rescaling
    x and y by a sufficiently large power of 2 to ensure that x and y
    are normal.
    '''
    if not isfinite(x) or not isfinite(y):
        return sqrt_special_values[special_type(x)][special_type(y)]

    if x == 0. and y == 0.:
        return (0., y)

    ax = fabs(x)
    ay = fabs(y)

    if ax < DBL_MIN and ay < DBL_MIN and (ax > 0. or ay > 0.):
        # here we catch cases where hypot(ax, ay) is subnormal
        ax = math.ldexp(ax, CM_SCALE_UP)
        ay1= math.ldexp(ay, CM_SCALE_UP)
        s = math.ldexp(math.sqrt(ax + math.hypot(ax, ay1)),
                       CM_SCALE_DOWN)
    else:
        ax /= 8.
        s = 2.*math.sqrt(ax + math.hypot(ax, ay/8.))

    d = ay/(2.*s)

    if x >= 0.:
        return (s, copysign(d, y))
    else:
        return (d, copysign(s, y))
示例#16
0
文件: rcomplex.py 项目: sota/pypy-old
def c_sqrt(x, y):
    '''
    Method: use symmetries to reduce to the case when x = z.real and y
    = z.imag are nonnegative.  Then the real part of the result is
    given by
    
      s = sqrt((x + hypot(x, y))/2)
    
    and the imaginary part is
    
      d = (y/2)/s
    
    If either x or y is very large then there's a risk of overflow in
    computation of the expression x + hypot(x, y).  We can avoid this
    by rewriting the formula for s as:
    
      s = 2*sqrt(x/8 + hypot(x/8, y/8))
    
    This costs us two extra multiplications/divisions, but avoids the
    overhead of checking for x and y large.
    
    If both x and y are subnormal then hypot(x, y) may also be
    subnormal, so will lack full precision.  We solve this by rescaling
    x and y by a sufficiently large power of 2 to ensure that x and y
    are normal.
    '''
    if not isfinite(x) or not isfinite(y):
        return sqrt_special_values[special_type(x)][special_type(y)]

    if x == 0. and y == 0.:
        return (0., y)

    ax = fabs(x)
    ay = fabs(y)

    if ax < DBL_MIN and ay < DBL_MIN and (ax > 0. or ay > 0.):
        # here we catch cases where hypot(ax, ay) is subnormal
        ax = math.ldexp(ax, CM_SCALE_UP)
        ay1 = math.ldexp(ay, CM_SCALE_UP)
        s = math.ldexp(math.sqrt(ax + math.hypot(ax, ay1)), CM_SCALE_DOWN)
    else:
        ax /= 8.
        s = 2. * math.sqrt(ax + math.hypot(ax, ay / 8.))

    d = ay / (2. * s)

    if x >= 0.:
        return (s, copysign(d, y))
    else:
        return (d, copysign(s, y))
示例#17
0
文件: ll_math.py 项目: soIu/rpython
def ll_math_atan2(y, x):
    """wrapper for atan2 that deals directly with special cases before
    delegating to the platform libm for the remaining cases.  This
    is necessary to get consistent behaviour across platforms.
    Windows, FreeBSD and alpha Tru64 are amongst platforms that don't
    always follow C99.
    """
    if math.isnan(x):
        return NAN

    if not isfinite(y):
        if math.isnan(y):
            return NAN
        if math.isinf(x):
            if math_copysign(1.0, x) == 1.0:
                # atan2(+-inf, +inf) == +-pi/4
                return math_copysign(0.25 * math.pi, y)
            else:
                # atan2(+-inf, -inf) == +-pi*3/4
                return math_copysign(0.75 * math.pi, y)
        # atan2(+-inf, x) == +-pi/2 for finite x
        return math_copysign(0.5 * math.pi, y)

    if math.isinf(x) or y == 0.0:
        if math_copysign(1.0, x) == 1.0:
            # atan2(+-y, +inf) = atan2(+-0, +x) = +-0.
            return math_copysign(0.0, y)
        else:
            # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi.
            return math_copysign(math.pi, y)

    return math_atan2(y, x)
示例#18
0
文件: ll_math.py 项目: mozillazg/pypy
def ll_math_atan2(y, x):
    """wrapper for atan2 that deals directly with special cases before
    delegating to the platform libm for the remaining cases.  This
    is necessary to get consistent behaviour across platforms.
    Windows, FreeBSD and alpha Tru64 are amongst platforms that don't
    always follow C99.
    """
    if isnan(x):
        return NAN

    if not isfinite(y):
        if isnan(y):
            return NAN
        if isinf(x):
            if math_copysign(1.0, x) == 1.0:
                # atan2(+-inf, +inf) == +-pi/4
                return math_copysign(0.25 * math.pi, y)
            else:
                # atan2(+-inf, -inf) == +-pi*3/4
                return math_copysign(0.75 * math.pi, y)
        # atan2(+-inf, x) == +-pi/2 for finite x
        return math_copysign(0.5 * math.pi, y)

    if isinf(x) or y == 0.0:
        if math_copysign(1.0, x) == 1.0:
            # atan2(+-y, +inf) = atan2(+-0, +x) = +-0.
            return math_copysign(0.0, y)
        else:
            # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi.
            return math_copysign(math.pi, y)

    return math_atan2(y, x)
示例#19
0
文件: node.py 项目: hmrg-grmh/pypy
def generic_initializationexpr(db, value, access_expr, decoration):
    if isinstance(typeOf(value), ContainerType):
        node = db.getcontainernode(value)
        lines = list(node.initializationexpr(decoration+'.'))
        lines[-1] += ','
        return lines
    else:
        comma = ','
        if typeOf(value) == Float and not isfinite(value):
            db.late_initializations.append(('%s' % access_expr, db.get(value)))
            if math.isinf(value):
                name = '-+'[value > 0] + 'inf'
            else:
                name = 'NaN'
            expr = '0.0 /* patched later with %s */' % (name,)
        else:
            expr = db.get(value)
            if typeOf(value) is Void:
                comma = ''
        expr += comma
        i = expr.find('\n')
        if i < 0:
            i = len(expr)
        expr = '%s\t/* %s */%s' % (expr[:i], decoration, expr[i:])
        return expr.split('\n')
示例#20
0
def _round_float(space, w_float, w_ndigits=None):
    # Algorithm copied directly from CPython
    x = w_float.floatval

    if w_ndigits is None:
        # single-argument round: round to nearest integer
        rounded = rfloat.round_away(x)
        if math.fabs(x - rounded) == 0.5:
            # halfway case: round to even
            rounded = 2.0 * rfloat.round_away(x / 2.0)
        return newlong_from_float(space, rounded)

    # interpret 2nd argument as a Py_ssize_t; clip on overflow
    ndigits = space.getindex_w(w_ndigits, None)

    # nans and infinities round to themselves
    if not rfloat.isfinite(x):
        return space.newfloat(x)

    # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
    # always rounds to itself.  For ndigits < NDIGITS_MIN, x always
    # rounds to +-0.0
    if ndigits > NDIGITS_MAX:
        return space.newfloat(x)
    elif ndigits < NDIGITS_MIN:
        # return 0.0, but with sign of x
        return space.newfloat(0.0 * x)

    # finite x, and ndigits is not unreasonably large
    z = rfloat.round_double(x, ndigits, half_even=True)
    if math.isinf(z):
        raise oefmt(space.w_OverflowError, "overflow occurred during round")
    return space.newfloat(z)
示例#21
0
def _hash_float(space, v):
    if not isfinite(v):
        if math.isinf(v):
            return HASH_INF if v > 0 else -HASH_INF
        return HASH_NAN

    m, e = math.frexp(v)

    sign = 1
    if m < 0:
        sign = -1
        m = -m

    # process 28 bits at a time;  this should work well both for binary
    # and hexadecimal floating point.
    x = r_uint(0)
    while m:
        x = ((x << 28) & HASH_MODULUS) | x >> (HASH_BITS - 28)
        m *= 268435456.0  # 2**28
        e -= 28
        y = r_uint(m)  # pull out integer part
        m -= y
        x += y
        if x >= HASH_MODULUS:
            x -= HASH_MODULUS

    # adjust for the exponent;  first reduce it modulo HASH_BITS
    e = e % HASH_BITS if e >= 0 else HASH_BITS - 1 - ((-1 - e) % HASH_BITS)
    x = ((x << e) & HASH_MODULUS) | x >> (HASH_BITS - e)

    x = intmask(intmask(x) * sign)
    return -2 if x == -1 else x
示例#22
0
文件: node.py 项目: GaussDing/pypy
def generic_initializationexpr(db, value, access_expr, decoration):
    if isinstance(typeOf(value), ContainerType):
        node = db.getcontainernode(value)
        lines = list(node.initializationexpr(decoration + "."))
        lines[-1] += ","
        return lines
    else:
        comma = ","
        if typeOf(value) == Float and not isfinite(value):
            db.late_initializations.append(("%s" % access_expr, db.get(value)))
            if isinf(value):
                name = "-+"[value > 0] + "inf"
            else:
                name = "NaN"
            expr = "0.0 /* patched later with %s */" % (name,)
        else:
            expr = db.get(value)
            if typeOf(value) is Void:
                comma = ""
        expr += comma
        i = expr.find("\n")
        if i < 0:
            i = len(expr)
        expr = "%s\t/* %s */%s" % (expr[:i], decoration, expr[i:])
        return expr.split("\n")
示例#23
0
def _round_float(space, w_float, w_ndigits=None):
    # Algorithm copied directly from CPython
    x = w_float.floatval

    if w_ndigits is None:
        # single-argument round: round to nearest integer
        rounded = rfloat.round_away(x)
        if math.fabs(x - rounded) == 0.5:
            # halfway case: round to even
            rounded = 2.0 * rfloat.round_away(x / 2.0)
        return newlong_from_float(space, rounded)

    # interpret 2nd argument as a Py_ssize_t; clip on overflow
    ndigits = space.getindex_w(w_ndigits, None)

    # nans and infinities round to themselves
    if not rfloat.isfinite(x):
        return space.wrap(x)

    # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
    # always rounds to itself.  For ndigits < NDIGITS_MIN, x always
    # rounds to +-0.0
    if ndigits > NDIGITS_MAX:
        return space.wrap(x)
    elif ndigits < NDIGITS_MIN:
        # return 0.0, but with sign of x
        return space.wrap(0.0 * x)

    # finite x, and ndigits is not unreasonably large
    z = rfloat.round_double(x, ndigits, half_even=True)
    if rfloat.isinf(z):
        raise oefmt(space.w_OverflowError, "overflow occurred during round")
    return space.wrap(z)
示例#24
0
def _hash_float(space, v):
    if not isfinite(v):
        if isinf(v):
            return HASH_INF if v > 0 else -HASH_INF
        return HASH_NAN

    m, e = math.frexp(v)

    sign = 1
    if m < 0:
        sign = -1
        m = -m

    # process 28 bits at a time;  this should work well both for binary
    # and hexadecimal floating point.
    x = r_uint(0)
    while m:
        x = ((x << 28) & HASH_MODULUS) | x >> (HASH_BITS - 28)
        m *= 268435456.0  # 2**28
        e -= 28
        y = r_uint(m)  # pull out integer part
        m -= y
        x += y
        if x >= HASH_MODULUS:
            x -= HASH_MODULUS

    # adjust for the exponent;  first reduce it modulo HASH_BITS
    e = e % HASH_BITS if e >= 0 else HASH_BITS - 1 - ((-1 - e) % HASH_BITS)
    x = ((x << e) & HASH_MODULUS) | x >> (HASH_BITS - e)

    x = intmask(intmask(x) * sign)
    return -2 if x == -1 else x
示例#25
0
def round(space, number, w_ndigits):
    """round(number[, ndigits]) -> floating point number

Round a number to a given precision in decimal digits (default 0 digits).
This always returns a floating point number.  Precision may be negative."""
    # Algorithm copied directly from CPython

    # interpret 2nd argument as a Py_ssize_t; clip on overflow
    ndigits = space.getindex_w(w_ndigits, None)

    # nans, infinities and zeros round to themselves
    if not isfinite(number):
        z = number
    elif ndigits == 0:  # common case
        z = round_away(number)
        # no need to check for an infinite 'z' here
    else:
        # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
        # always rounds to itself.  For ndigits < NDIGITS_MIN, x always
        # rounds to +-0.0.
        if ndigits > NDIGITS_MAX:
            z = number
        elif ndigits < NDIGITS_MIN:
            # return 0.0, but with sign of x
            z = 0.0 * number
        else:
            # finite x, and ndigits is not unreasonably large
            z = round_double(number, ndigits)
            if isinf(z):
                raise oefmt(space.w_OverflowError,
                            "rounded value too large to represent")
    return space.newfloat(z)
示例#26
0
 def descr_hex(self, space):
     TOHEX_NBITS = rfloat.DBL_MANT_DIG + 3 - (rfloat.DBL_MANT_DIG + 2) % 4
     value = self.floatval
     if not isfinite(value):
         return self.descr_str(space)
     if value == 0.0:
         if copysign(1., value) == -1.:
             return space.wrap("-0x0.0p+0")
         else:
             return space.wrap("0x0.0p+0")
     mant, exp = math.frexp(value)
     shift = 1 - max(rfloat.DBL_MIN_EXP - exp, 0)
     mant = math.ldexp(mant, shift)
     mant = abs(mant)
     exp -= shift
     result = ['\0'] * ((TOHEX_NBITS - 1) // 4 + 2)
     result[0] = _char_from_hex(int(mant))
     mant -= int(mant)
     result[1] = "."
     for i in range((TOHEX_NBITS - 1) // 4):
         mant *= 16.0
         result[i + 2] = _char_from_hex(int(mant))
         mant -= int(mant)
     if exp < 0:
         sign = "-"
     else:
         sign = "+"
     exp = abs(exp)
     s = ''.join(result)
     if value < 0.0:
         return space.wrap("-0x%sp%s%d" % (s, sign, exp))
     else:
         return space.wrap("0x%sp%s%d" % (s, sign, exp))
示例#27
0
文件: node.py 项目: sota/pypy
def generic_initializationexpr(db, value, access_expr, decoration):
    if isinstance(typeOf(value), ContainerType):
        node = db.getcontainernode(value)
        lines = list(node.initializationexpr(decoration+'.'))
        lines[-1] += ','
        return lines
    else:
        comma = ','
        if typeOf(value) == Float and not isfinite(value):
            db.late_initializations.append(('%s' % access_expr, db.get(value)))
            if isinf(value):
                name = '-+'[value > 0] + 'inf'
            else:
                name = 'NaN'
            expr = '0.0 /* patched later with %s */' % (name,)
        else:
            expr = db.get(value)
            if typeOf(value) is Void:
                comma = ''
        expr += comma
        i = expr.find('\n')
        if i < 0:
            i = len(expr)
        expr = '%s\t/* %s */%s' % (expr[:i], decoration, expr[i:])
        return expr.split('\n')
示例#28
0
文件: rcomplex.py 项目: sota/pypy-old
def c_acosh(x, y):
    # XXX the following two lines seem unnecessary at least on Linux;
    # the tests pass fine without them
    if not isfinite(x) or not isfinite(y):
        return acosh_special_values[special_type(x)][special_type(y)]

    if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE:
        # avoid unnecessary overflow for large arguments
        real = math.log(math.hypot(x / 2., y / 2.)) + M_LN2 * 2.
        imag = math.atan2(y, x)
    else:
        s1x, s1y = c_sqrt(x - 1., y)
        s2x, s2y = c_sqrt(x + 1., y)
        real = asinh(s1x * s2x + s1y * s2y)
        imag = 2. * math.atan2(s1y, s2x)
    return (real, imag)
示例#29
0
文件: rcomplex.py 项目: Darriall/pypy
def c_acosh(x, y):
    # XXX the following two lines seem unnecessary at least on Linux;
    # the tests pass fine without them
    if not isfinite(x) or not isfinite(y):
        return acosh_special_values[special_type(x)][special_type(y)]

    if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE:
        # avoid unnecessary overflow for large arguments
        real = math.log(math.hypot(x/2., y/2.)) + M_LN2*2.
        imag = math.atan2(y, x)
    else:
        s1x, s1y = c_sqrt(x - 1., y)
        s2x, s2y = c_sqrt(x + 1., y)
        real = asinh(s1x*s2x + s1y*s2y)
        imag = 2.*math.atan2(s1y, s2x)
    return (real, imag)
示例#30
0
文件: ll_math.py 项目: soIu/rpython
def ll_math_sqrt(x):
    if x < 0.0:
        raise ValueError("math domain error")

    if isfinite(x):
        return sqrt_nonneg(x)

    return x  # +inf or nan
示例#31
0
文件: rcomplex.py 项目: sota/pypy-old
def c_abs(r, i):
    if not isfinite(r) or not isfinite(i):
        # C99 rules: if either the real or the imaginary part is an
        # infinity, return infinity, even if the other part is a NaN.
        if isinf(r):
            return INF
        if isinf(i):
            return INF

        # either the real or imaginary part is a NaN,
        # and neither is infinite. Result should be NaN.
        return NAN

    result = math.hypot(r, i)
    if not isfinite(result):
        raise OverflowError("math range error")
    return result
示例#32
0
文件: ll_math.py 项目: mozillazg/pypy
def ll_math_sqrt(x):
    if x < 0.0:
        raise ValueError("math domain error")

    if isfinite(x):
        return sqrt_nonneg(x)

    return x   # +inf or nan
示例#33
0
文件: rcomplex.py 项目: Darriall/pypy
def c_abs(r, i):
    if not isfinite(r) or not isfinite(i):
        # C99 rules: if either the real or the imaginary part is an
        # infinity, return infinity, even if the other part is a NaN.
        if isinf(r):
            return INF
        if isinf(i):
            return INF

        # either the real or imaginary part is a NaN,
        # and neither is infinite. Result should be NaN.
        return NAN

    result = math.hypot(r, i)
    if not isfinite(result):
        raise OverflowError("math range error")
    return result
示例#34
0
def float_pack80(x, size):
    """Convert a Python float or longfloat x into two 64-bit unsigned integers
    with 80 bit extended representation."""
    x = float(x)  # longfloat not really supported
    if size == 10 or size == 12 or size == 16:
        MIN_EXP = -16381
        MAX_EXP = 16384
        MANT_DIG = 64
        BITS = 80
    else:
        raise ValueError("invalid size value")

    sign = rfloat.copysign(1.0, x) < 0.0
    if not rfloat.isfinite(x):
        if rfloat.isinf(x):
            mant = r_ulonglong(0)
            exp = MAX_EXP - MIN_EXP + 2
        else:  # rfloat.isnan(x):
            mant = (r_ulonglong(1) <<
                    (MANT_DIG - 2)) - 1  # other values possible
            exp = MAX_EXP - MIN_EXP + 2
    elif x == 0.0:
        mant = r_ulonglong(0)
        exp = 0
    else:
        m, e = math.frexp(abs(x))  # abs(x) == m * 2**e
        exp = e - (MIN_EXP - 1)
        if exp > 0:
            # Normal case. Avoid uint64 overflow by using MANT_DIG-1
            mant = round_to_nearest(m * (r_ulonglong(1) << MANT_DIG - 1))
        else:
            # Subnormal case.
            if exp + MANT_DIG - 1 >= 0:
                mant = round_to_nearest(m *
                                        (r_ulonglong(1) << exp + MANT_DIG - 1))
            else:
                mant = r_ulonglong(0)
            exp = 0

        # Special case: rounding produced a MANT_DIG-bit mantissa.
        if mant == r_ulonglong(1) << MANT_DIG - 1:
            mant = r_ulonglong(0)
            exp += 1

        # Raise on overflow (in some circumstances, may want to return
        # infinity instead).
        if exp >= MAX_EXP - MIN_EXP + 2:
            raise OverflowError("float too large to pack in this format")

    # check constraints
    if not objectmodel.we_are_translated():
        assert 0 <= mant < 1 << MANT_DIG - 1
        assert 0 <= exp <= MAX_EXP - MIN_EXP + 2
        assert 0 <= sign <= 1
    mant = mant << 1
    exp = r_ulonglong(exp)
    sign = r_ulonglong(sign)
    return (mant, (sign << BITS - MANT_DIG - 1) | exp)
示例#35
0
文件: rcomplex.py 项目: Darriall/pypy
def c_asinh(x, y):
    if not isfinite(x) or not isfinite(y):
        return asinh_special_values[special_type(x)][special_type(y)]

    if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE:
        if y >= 0.:
            real = copysign(math.log(math.hypot(x/2., y/2.)) +
                            M_LN2*2., x)
        else:
            real = -copysign(math.log(math.hypot(x/2., y/2.)) +
                             M_LN2*2., -x)
        imag = math.atan2(y, fabs(x))
    else:
        s1x, s1y = c_sqrt(1.+y, -x)
        s2x, s2y = c_sqrt(1.-y, x)
        real = asinh(s1x*s2y - s2x*s1y)
        imag = math.atan2(y, s1x*s2x - s1y*s2y)
    return (real, imag)
示例#36
0
文件: rcomplex.py 项目: sota/pypy-old
def c_asinh(x, y):
    if not isfinite(x) or not isfinite(y):
        return asinh_special_values[special_type(x)][special_type(y)]

    if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE:
        if y >= 0.:
            real = copysign(
                math.log(math.hypot(x / 2., y / 2.)) + M_LN2 * 2., x)
        else:
            real = -copysign(
                math.log(math.hypot(x / 2., y / 2.)) + M_LN2 * 2., -x)
        imag = math.atan2(y, fabs(x))
    else:
        s1x, s1y = c_sqrt(1. + y, -x)
        s2x, s2y = c_sqrt(1. - y, x)
        real = asinh(s1x * s2y - s2x * s1y)
        imag = math.atan2(y, s1x * s2x - s1y * s2y)
    return (real, imag)
示例#37
0
 def do_compare_bigint(f1, b2):
     """f1 is a float.  b2 is a bigint."""
     if not isfinite(f1) or math.floor(f1) != f1:
         return opname == 'ne'
     b1 = rbigint.fromfloat(f1)
     res = b1.eq(b2)
     if opname == 'ne':
         res = not res
     return res
示例#38
0
文件: ll_math.py 项目: mozillazg/pypy
 def ll_math(x):
     r = c_func(x)
     # Error checking fun.  Copied from CPython 2.6
     errno = rposix.get_saved_errno()
     if not isfinite(r):
         if isnan(r):
             if isnan(x):
                 errno = 0
             else:
                 errno = EDOM
         else:  # isinf(r)
             if not isfinite(x):
                 errno = 0
             elif can_overflow:
                 errno = ERANGE
             else:
                 errno = EDOM
     if errno:
         _likely_raise(errno, r)
     return r
示例#39
0
文件: numbers.py 项目: cheery/lever
def float_to_string(x, code='g', precision=DTSF_STR_PRECISION):
    if isfinite(x):
        s = formatd(x, code, precision, DTSF_ADD_DOT_0)
    elif isinf(x):
        if x > 0.0:
            s = "inf"
        else:
            s = "-inf"
    else:  # isnan(x):
        s = "nan"
    return s.decode('utf-8')
示例#40
0
def float_to_string(x, code='g', precision=DTSF_STR_PRECISION):
    if isfinite(x):
        s = formatd(x, code, precision, DTSF_ADD_DOT_0)
    elif isinf(x):
        if x > 0.0:
            s = "inf"
        else:
            s = "-inf"
    else:  # isnan(x):
        s = "nan"
    return s.decode('utf-8')
示例#41
0
文件: ll_math.py 项目: soIu/rpython
 def ll_math(x):
     r = c_func(x)
     # Error checking fun.  Copied from CPython 2.6
     errno = rposix.get_saved_errno()
     if not isfinite(r):
         if math.isnan(r):
             if math.isnan(x):
                 errno = 0
             else:
                 errno = EDOM
         else:  # isinf(r)
             if not isfinite(x):
                 errno = 0
             elif can_overflow:
                 errno = ERANGE
             else:
                 errno = EDOM
     if errno:
         _likely_raise(errno, r)
     return r
示例#42
0
def float2string(x, code, precision):
    # we special-case explicitly inf and nan here
    if isfinite(x):
        s = formatd(x, code, precision, DTSF_ADD_DOT_0)
    elif isinf(x):
        if x > 0.0:
            s = "inf"
        else:
            s = "-inf"
    else:  # isnan(x):
        s = "nan"
    return s
示例#43
0
文件: rcomplex.py 项目: Darriall/pypy
def c_acos(x, y):
    if not isfinite(x) or not isfinite(y):
        return acos_special_values[special_type(x)][special_type(y)]

    if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE:
        # avoid unnecessary overflow for large arguments
        real = math.atan2(fabs(y), x)
        # split into cases to make sure that the branch cut has the
        # correct continuity on systems with unsigned zeros
        if x < 0.:
            imag = -copysign(math.log(math.hypot(x/2., y/2.)) +
                             M_LN2*2., y)
        else:
            imag = copysign(math.log(math.hypot(x/2., y/2.)) +
                            M_LN2*2., -y)
    else:
        s1x, s1y = c_sqrt(1.-x, -y)
        s2x, s2y = c_sqrt(1.+x, y)
        real = 2.*math.atan2(s1x, s2x)
        imag = asinh(s2x*s1y - s2y*s1x)
    return (real, imag)
示例#44
0
文件: rcomplex.py 项目: sota/pypy-old
def c_acos(x, y):
    if not isfinite(x) or not isfinite(y):
        return acos_special_values[special_type(x)][special_type(y)]

    if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE:
        # avoid unnecessary overflow for large arguments
        real = math.atan2(fabs(y), x)
        # split into cases to make sure that the branch cut has the
        # correct continuity on systems with unsigned zeros
        if x < 0.:
            imag = -copysign(
                math.log(math.hypot(x / 2., y / 2.)) + M_LN2 * 2., y)
        else:
            imag = copysign(
                math.log(math.hypot(x / 2., y / 2.)) + M_LN2 * 2., -y)
    else:
        s1x, s1y = c_sqrt(1. - x, -y)
        s2x, s2y = c_sqrt(1. + x, y)
        real = 2. * math.atan2(s1x, s2x)
        imag = asinh(s2x * s1y - s2y * s1x)
    return (real, imag)
示例#45
0
文件: rcomplex.py 项目: Darriall/pypy
def c_tanh(x, y):
    # Formula:
    #
    #   tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) /
    #   (1+tan(y)^2 tanh(x)^2)
    #
    #   To avoid excessive roundoff error, 1-tanh(x)^2 is better computed
    #   as 1/cosh(x)^2.  When abs(x) is large, we approximate 1-tanh(x)^2
    #   by 4 exp(-2*x) instead, to avoid possible overflow in the
    #   computation of cosh(x).

    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = 1.0        # vv XXX why is the 2. there?
                imag = copysign(0., 2. * math.sin(y) * math.cos(y))
            else:
                real = -1.0
                imag = copysign(0., 2. * math.sin(y) * math.cos(y))
            r = (real, imag)
        else:
            r = tanh_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/-infinity and x is finite
        if isinf(y) and isfinite(x):
            raise ValueError("math domain error")
        return r

    if fabs(x) > CM_LOG_LARGE_DOUBLE:
        real = copysign(1., x)
        imag = 4. * math.sin(y) * math.cos(y) * math.exp(-2.*fabs(x))
    else:
        tx = math.tanh(x)
        ty = math.tan(y)
        cx = 1. / math.cosh(x)
        txty = tx * ty
        denom = 1. + txty * txty
        real = tx * (1. + ty*ty) / denom
        imag = ((ty / denom) * cx) * cx
    return real, imag
示例#46
0
文件: rcomplex.py 项目: sota/pypy-old
def c_tanh(x, y):
    # Formula:
    #
    #   tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) /
    #   (1+tan(y)^2 tanh(x)^2)
    #
    #   To avoid excessive roundoff error, 1-tanh(x)^2 is better computed
    #   as 1/cosh(x)^2.  When abs(x) is large, we approximate 1-tanh(x)^2
    #   by 4 exp(-2*x) instead, to avoid possible overflow in the
    #   computation of cosh(x).

    if not isfinite(x) or not isfinite(y):
        if isinf(x) and isfinite(y) and y != 0.:
            if x > 0:
                real = 1.0  # vv XXX why is the 2. there?
                imag = copysign(0., 2. * math.sin(y) * math.cos(y))
            else:
                real = -1.0
                imag = copysign(0., 2. * math.sin(y) * math.cos(y))
            r = (real, imag)
        else:
            r = tanh_special_values[special_type(x)][special_type(y)]

        # need to raise ValueError if y is +/-infinity and x is finite
        if isinf(y) and isfinite(x):
            raise ValueError("math domain error")
        return r

    if fabs(x) > CM_LOG_LARGE_DOUBLE:
        real = copysign(1., x)
        imag = 4. * math.sin(y) * math.cos(y) * math.exp(-2. * fabs(x))
    else:
        tx = math.tanh(x)
        ty = math.tan(y)
        cx = 1. / math.cosh(x)
        txty = tx * ty
        denom = 1. + txty * txty
        real = tx * (1. + ty * ty) / denom
        imag = ((ty / denom) * cx) * cx
    return real, imag
示例#47
0
文件: ll_math.py 项目: mozillazg/pypy
def ll_math_frexp(x):
    # deal with special cases directly, to sidestep platform differences
    if not isfinite(x) or not x:
        mantissa = x
        exponent = 0
    else:
        exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
        try:
            mantissa = math_frexp(x, exp_p)
            exponent = rffi.cast(lltype.Signed, exp_p[0])
        finally:
            lltype.free(exp_p, flavor='raw')
    return (mantissa, exponent)
示例#48
0
def ll_math_frexp(x):
    # deal with special cases directly, to sidestep platform differences
    if not isfinite(x) or not x:
        mantissa = x
        exponent = 0
    else:
        exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
        try:
            mantissa = math_frexp(x, exp_p)
            exponent = rffi.cast(lltype.Signed, exp_p[0])
        finally:
            lltype.free(exp_p, flavor='raw')
    return (mantissa, exponent)
示例#49
0
文件: ll_math.py 项目: mozillazg/pypy
def ll_math_hypot(x, y):
    # hypot(x, +/-Inf) returns Inf, even if x is a NaN.
    if isinf(x):
        return math_fabs(x)
    if isinf(y):
        return math_fabs(y)

    r = math_hypot(x, y)
    errno = rposix.get_saved_errno()
    if not isfinite(r):
        if isnan(r):
            if isnan(x) or isnan(y):
                errno = 0
            else:
                errno = EDOM
        else:  # isinf(r)
            if isfinite(x) and isfinite(y):
                errno = ERANGE
            else:
                errno = 0
    if errno:
        _likely_raise(errno, r)
    return r
示例#50
0
文件: ll_math.py 项目: soIu/rpython
def ll_math_hypot(x, y):
    # hypot(x, +/-Inf) returns Inf, even if x is a NaN.
    if math.isinf(x):
        return math_fabs(x)
    if math.isinf(y):
        return math_fabs(y)

    r = math_hypot(x, y)
    errno = rposix.get_saved_errno()
    if not isfinite(r):
        if math.isnan(r):
            if math.isnan(x) or math.isnan(y):
                errno = 0
            else:
                errno = EDOM
        else:  # isinf(r)
            if isfinite(x) and isfinite(y):
                errno = ERANGE
            else:
                errno = 0
    if errno:
        _likely_raise(errno, r)
    return r
示例#51
0
 def do_compare_bigint(f1, b2):
     """f1 is a float.  b2 is a bigint."""
     if not isfinite(f1):
         return op(f1, 0.0)
     if opname == 'gt' or opname == 'le':
         # 'float > long'   <==>  'ceil(float) > long'
         # 'float <= long'  <==>  'ceil(float) <= long'
         f1 = math.ceil(f1)
     else:
         # 'float < long'   <==>  'floor(float) < long'
         # 'float >= long'  <==>  'floor(float) >= long'
         f1 = math.floor(f1)
     b1 = rbigint.fromfloat(f1)
     return getattr(b1, opname)(b2)
示例#52
0
def fsum(space, w_iterable):
    """Sum an iterable of floats, trying to keep precision."""
    w_iter = space.iter(w_iterable)
    inf_sum = special_sum = 0.0
    partials = []
    while True:
        try:
            w_value = space.next(w_iter)
        except OperationError, e:
            if not e.match(space, space.w_StopIteration):
                raise
            break
        v = _get_double(space, w_value)
        original = v
        added = 0
        for y in partials:
            if abs(v) < abs(y):
                v, y = y, v
            hi = v + y
            yr = hi - v
            lo = y - yr
            if lo != 0.0:
                partials[added] = lo
                added += 1
            v = hi
        del partials[added:]
        if v != 0.0:
            if not rfloat.isfinite(v):
                if rfloat.isfinite(original):
                    raise OperationError(space.w_OverflowError,
                                         space.wrap("intermediate overflow"))
                if rfloat.isinf(original):
                    inf_sum += original
                special_sum += original
                del partials[:]
            else:
                partials.append(v)
示例#53
0
文件: ll_math.py 项目: soIu/rpython
def ll_math_fmod(x, y):
    # fmod(x, +/-Inf) returns x for finite x.
    if math.isinf(y) and isfinite(x):
        return x

    r = math_fmod(x, y)
    errno = rposix.get_saved_errno()
    if math.isnan(r):
        if math.isnan(x) or math.isnan(y):
            errno = 0
        else:
            errno = EDOM
    if errno:
        _likely_raise(errno, r)
    return r
示例#54
0
文件: ll_math.py 项目: mozillazg/pypy
def ll_math_modf(x):
    # some platforms don't do the right thing for NaNs and
    # infinities, so we take care of special cases directly.
    if not isfinite(x):
        if isnan(x):
            return (x, x)
        else:   # isinf(x)
            return (math_copysign(0.0, x), x)
    intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw')
    try:
        fracpart = math_modf(x, intpart_p)
        intpart = intpart_p[0]
    finally:
        lltype.free(intpart_p, flavor='raw')
    return (fracpart, intpart)
示例#55
0
文件: ll_math.py 项目: mozillazg/pypy
def ll_math_fmod(x, y):
    # fmod(x, +/-Inf) returns x for finite x.
    if isinf(y) and isfinite(x):
        return x

    r = math_fmod(x, y)
    errno = rposix.get_saved_errno()
    if isnan(r):
        if isnan(x) or isnan(y):
            errno = 0
        else:
            errno = EDOM
    if errno:
        _likely_raise(errno, r)
    return r