Esempio n. 1
0
 def test_math_sqrt(self):
     def f(x):
         try:
             return math.sqrt(x)
         except ValueError:
             return -INFINITY
     
     res = self.interp_operations(f, [0.0])
     assert res == 0.0
     self.check_operations_history(call_pure=1)
     #
     res = self.interp_operations(f, [25.0])
     assert res == 5.0
     self.check_operations_history(call_pure=1)
     #
     res = self.interp_operations(f, [-0.0])
     assert str(res) == '-0.0'
     self.check_operations_history(call_pure=1)
     #
     res = self.interp_operations(f, [1000000.0])
     assert res == 1000.0
     self.check_operations_history(call_pure=1)
     #
     res = self.interp_operations(f, [-1.0])
     assert res == -INFINITY
     self.check_operations_history(call_pure=0)
     #
     res = self.interp_operations(f, [INFINITY])
     assert isinf(res) and not isnan(res) and res > 0.0
     self.check_operations_history(call_pure=0)
     #
     res = self.interp_operations(f, [NAN])
     assert isnan(res) and not isinf(res)
     self.check_operations_history(call_pure=0)
Esempio n. 2
0
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) or isnan(y):
        return NAN

    if isinf(y):
        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)
Esempio n. 3
0
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)
Esempio n. 4
0
def AbstractEC(ctx, x, y):
    """
    Implements the Abstract Equality Comparison x == y
    trying to be fully to the spec
    """
    if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber):
        return x.intval == y.intval
    if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber):
        if isnan(x.floatval) or isnan(y.floatval):
            return False
        return x.floatval == y.floatval
    type1 = x.type()
    type2 = y.type()
    if type1 == type2:
        if type1 == "undefined" or type1 == "null":
            return True
        if type1 == "number":
            n1 = x.ToNumber(ctx)
            n2 = y.ToNumber(ctx)
            if isnan(n1) or isnan(n2):
                return False
            if n1 == n2:
                return True
            return False
        elif type1 == "string":
            return x.ToString(ctx) == y.ToString(ctx)
        elif type1 == "boolean":
            return x.ToBoolean() == x.ToBoolean()
        # XXX rethink it here
        return x.ToString(ctx) == y.ToString(ctx)
    else:
        # step 14
        if (type1 == "undefined" and type2 == "null") or (type1 == "null" and type2 == "undefined"):
            return True
        if type1 == "number" and type2 == "string":
            return AbstractEC(ctx, x, W_FloatNumber(y.ToNumber(ctx)))
        if type1 == "string" and type2 == "number":
            return AbstractEC(ctx, W_FloatNumber(x.ToNumber(ctx)), y)
        if type1 == "boolean":
            return AbstractEC(ctx, W_FloatNumber(x.ToNumber(ctx)), y)
        if type2 == "boolean":
            return AbstractEC(ctx, x, W_FloatNumber(y.ToNumber(ctx)))
        if (type1 == "string" or type1 == "number") and type2 == "object":
            return AbstractEC(ctx, x, y.ToPrimitive(ctx))
        if (type2 == "string" or type2 == "number") and type1 == "object":
            return AbstractEC(ctx, x.ToPrimitive(ctx), y)
        return False

    objtype = x.GetValue().type()
    if objtype == y.GetValue().type():
        if objtype == "undefined" or objtype == "null":
            return True

    if isinstance(x, W_String) and isinstance(y, W_String):
        r = x.ToString(ctx) == y.ToString(ctx)
    else:
        r = x.ToNumber(ctx) == y.ToNumber(ctx)
    return r
Esempio n. 5
0
 def check_roundtrip(x):
     s = c_pack(x)
     assert s == pack(x)
     if not isnan(x):
         assert unpack(s) == x
         assert c_unpack(s) == x
     else:
         assert isnan(unpack(s))
         assert isnan(c_unpack(s))
Esempio n. 6
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
Esempio n. 7
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
Esempio n. 8
0
 def __eq__(self, other):
     if (type(self) is SomeFloat and type(other) is SomeFloat
             and self.is_constant() and other.is_constant()):
         from pypy.rlib.rfloat import isnan, copysign
         # NaN unpleasantness.
         if isnan(self.const) and isnan(other.const):
             return True
         # 0.0 vs -0.0 unpleasantness.
         if not self.const and not other.const:
             return copysign(1., self.const) == copysign(1., other.const)
         #
     return super(SomeFloat, self).__eq__(other)
Esempio n. 9
0
 def __eq__(self, other):
     if (type(self) is SomeFloat and type(other) is SomeFloat and
         self.is_constant() and other.is_constant()):
         from pypy.rlib.rfloat import isnan, copysign
         # NaN unpleasantness.
         if isnan(self.const) and isnan(other.const):
             return True
         # 0.0 vs -0.0 unpleasantness.
         if not self.const and not other.const:
             return copysign(1., self.const) == copysign(1., other.const)
         #
     return super(SomeFloat, self).__eq__(other)
Esempio n. 10
0
def rAssertAlmostEqual(a, b, rel_err = 2e-15, abs_err = 5e-323, msg=''):
    """Fail if the two floating-point numbers are not almost equal.

    Determine whether floating-point values a and b are equal to within
    a (small) rounding error.  The default values for rel_err and
    abs_err are chosen to be suitable for platforms where a float is
    represented by an IEEE 754 double.  They allow an error of between
    9 and 19 ulps.
    """

    # special values testing
    if isnan(a):
        if isnan(b):
            return
        raise AssertionError(msg + '%r should be nan' % (b,))

    if isinf(a):
        if a == b:
            return
        raise AssertionError(msg + 'finite result where infinity expected: '
                                   'expected %r, got %r' % (a, b))

    # if both a and b are zero, check whether they have the same sign
    # (in theory there are examples where it would be legitimate for a
    # and b to have opposite signs; in practice these hardly ever
    # occur).
    if not a and not b:
        # only check it if we are running on top of CPython >= 2.6
        if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b):
            raise AssertionError(msg + 'zero has wrong sign: expected %r, '
                                       'got %r' % (a, b))

    # if a-b overflows, or b is infinite, return False.  Again, in
    # theory there are examples where a is within a few ulps of the
    # max representable float, and then b could legitimately be
    # infinite.  In practice these examples are rare.
    try:
        absolute_error = abs(b-a)
    except OverflowError:
        pass
    else:
        # test passes if either the absolute error or the relative
        # error is sufficiently small.  The defaults amount to an
        # error of between 9 ulps and 19 ulps on an IEEE-754 compliant
        # machine.
        if absolute_error <= max(abs_err, rel_err * abs(a)):
            return
    raise AssertionError(msg + '%r and %r are not sufficiently close' % (a, b))
Esempio n. 11
0
def rAssertAlmostEqual(a, b, rel_err=2e-15, abs_err=5e-323, msg=''):
    """Fail if the two floating-point numbers are not almost equal.

    Determine whether floating-point values a and b are equal to within
    a (small) rounding error.  The default values for rel_err and
    abs_err are chosen to be suitable for platforms where a float is
    represented by an IEEE 754 double.  They allow an error of between
    9 and 19 ulps.
    """

    # special values testing
    if isnan(a):
        if isnan(b):
            return
        raise AssertionError(msg + '%r should be nan' % (b, ))

    if isinf(a):
        if a == b:
            return
        raise AssertionError(msg + 'finite result where infinity expected: '
                             'expected %r, got %r' % (a, b))

    # if both a and b are zero, check whether they have the same sign
    # (in theory there are examples where it would be legitimate for a
    # and b to have opposite signs; in practice these hardly ever
    # occur).
    if not a and not b:
        # only check it if we are running on top of CPython >= 2.6
        if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b):
            raise AssertionError(msg + 'zero has wrong sign: expected %r, '
                                 'got %r' % (a, b))

    # if a-b overflows, or b is infinite, return False.  Again, in
    # theory there are examples where a is within a few ulps of the
    # max representable float, and then b could legitimately be
    # infinite.  In practice these examples are rare.
    try:
        absolute_error = abs(b - a)
    except OverflowError:
        pass
    else:
        # test passes if either the absolute error or the relative
        # error is sufficiently small.  The defaults amount to an
        # error of between 9 ulps and 19 ulps on an IEEE-754 compliant
        # machine.
        if absolute_error <= max(abs_err, rel_err * abs(a)):
            return
    raise AssertionError(msg + '%r and %r are not sufficiently close' % (a, b))
Esempio n. 12
0
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
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
def test_nan_and_special_values():
    from pypy.rlib.rfloat import isnan, isinf, isfinite, copysign
    inf = 1e300 * 1e300
    assert isinf(inf)
    nan = inf/inf
    assert isnan(nan)

    for value, checker in [
            (inf,   lambda x: isinf(x) and x > 0.0),
            (-inf,  lambda x: isinf(x) and x < 0.0),
            (nan,   isnan),
            (42.0,  isfinite),
            (0.0,   lambda x: not x and copysign(1., x) == 1.),
            (-0.0,  lambda x: not x and copysign(1., x) == -1.),
            ]:
        def f():
            return value
        f1 = compile(f, [])
        res = f1()
        assert checker(res)

        l = [value]
        def g(x):
            return l[x]
        g2 = compile(g, [int])
        res = g2(0)
        assert checker(res)

        l2 = [(-value, -value), (value, value)]
        def h(x):
            return l2[x][1]
        h3 = compile(h, [int])
        res = h3(1)
        assert checker(res)
Esempio n. 16
0
 def format_float(self, w_value, char):
     space = self.space
     x = space.float_w(maybe_float(space, w_value))
     if isnan(x):
         if char in 'EFG':
             r = 'NAN'
         else:
             r = 'nan'
     elif isinf(x):
         if x < 0:
             if char in 'EFG':
                 r = '-INF'
             else:
                 r = '-inf'
         else:
             if char in 'EFG':
                 r = 'INF'
             else:
                 r = 'inf'
     else:
         prec = self.prec
         if prec < 0:
             prec = 6
         if char in 'fF' and x / 1e25 > 1e25:
             char = chr(ord(char) + 1)  # 'f' => 'g'
         flags = 0
         if self.f_alt:
             flags |= DTSF_ALT
         r = formatd(x, char, prec, flags)
     self.std_wp_number(r)
Esempio n. 17
0
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
Esempio n. 18
0
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
Esempio n. 19
0
 def ovfcheck_float_to_int(x):
     from pypy.rlib.rfloat import isnan
     if isnan(x):
         raise OverflowError
     if -9223372036854776832.0 <= x < 9223372036854775296.0:
         return int(x)
     raise OverflowError
Esempio n. 20
0
def str__Complex(space, w_complex):
    if w_complex.realval == 0 and copysign(1., w_complex.realval) == 1.:
        return space.wrap(str_format(w_complex.imagval) + 'j')
    sign = (copysign(1., w_complex.imagval) == 1. or
            isnan(w_complex.imagval)) and '+' or ''
    return space.wrap('(' + str_format(w_complex.realval)
                      + sign + str_format(w_complex.imagval) + 'j)')
Esempio n. 21
0
 def ovfcheck_float_to_int(x):
     from pypy.rlib.rfloat import isnan
     if isnan(x):
         raise OverflowError
     if -9223372036854776832.0 <= x < 9223372036854775296.0:
         return int(x)
     raise OverflowError
Esempio n. 22
0
 def ovfcheck_float_to_int(x):
     from pypy.rlib.rfloat import isnan
     if isnan(x):
         raise OverflowError
     if -2147483649.0 < x < 2147483648.0:
         return int(x)
     raise OverflowError
Esempio n. 23
0
 def ovfcheck_float_to_int(x):
     from pypy.rlib.rfloat import isnan
     if isnan(x):
         raise OverflowError
     if -2147483649.0 < x < 2147483648.0:
         return int(x)
     raise OverflowError
Esempio n. 24
0
def round(space, number, w_ndigits=0):
    """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 number == 0 or isinf(number) or isnan(number):
        return space.wrap(number)

    # 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(number)
    elif ndigits < NDIGITS_MIN:
        # return 0.0, but with sign of x
        return space.wrap(0.0 * number)

    # finite x, and ndigits is not unreasonably large
    z = round_double(number, ndigits)
    if isinf(z):
        raise OperationError(
            space.w_OverflowError,
            space.wrap("rounded value too large to represent"))
    return space.wrap(z)
Esempio n. 25
0
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
Esempio n. 26
0
def ll_math_fmod(x, y):
    # fmod(x, +/-Inf) returns x for finite x.
    if isinf(y) and isfinite(x):
        return x

    _error_reset()
    r = math_fmod(x, y)
    errno = rposix.get_errno()
    if isnan(r):
        if isnan(x) or isnan(y):
            errno = 0
        else:
            errno = EDOM
    if errno:
        _likely_raise(errno, r)
    return r
Esempio n. 27
0
 def format_float(self, w_value, char):
     space = self.space
     x = space.float_w(maybe_float(space, w_value))
     if isnan(x):
         if char in 'EFG':
             r = 'NAN'
         else:
             r = 'nan'
     elif isinf(x):
         if x < 0:
             if char in 'EFG':
                 r = '-INF'
             else:
                 r = '-inf'
         else:
             if char in 'EFG':
                 r = 'INF'
             else:
                 r = 'inf'
     else:
         prec = self.prec
         if prec < 0:
             prec = 6
         if char in 'fF' and x/1e25 > 1e25:
             char = chr(ord(char) + 1)     # 'f' => 'g'
         flags = 0
         if self.f_alt:
             flags |= DTSF_ALT
         r = formatd(x, char, prec, flags)
     self.std_wp_number(r)
Esempio n. 28
0
 def push_primitive_constant(self, TYPE, value):
     ilasm = self.ilasm
     if TYPE is ootype.Void:
         pass
     elif TYPE is ootype.Bool:
         ilasm.opcode("ldc.i4", str(int(value)))
     elif TYPE is ootype.Char or TYPE is ootype.UniChar:
         ilasm.opcode("ldc.i4", ord(value))
     elif TYPE is ootype.Float:
         if isinf(value):
             if value < 0.0:
                 ilasm.opcode("ldc.r8", "(00 00 00 00 00 00 f0 ff)")
             else:
                 ilasm.opcode("ldc.r8", "(00 00 00 00 00 00 f0 7f)")
         elif isnan(value):
             ilasm.opcode("ldc.r8", "(00 00 00 00 00 00 f8 ff)")
         else:
             ilasm.opcode("ldc.r8", repr(value))
     elif isinstance(value, CDefinedIntSymbolic):
         ilasm.opcode("ldc.i4", DEFINED_INT_SYMBOLICS[value.expr])
     elif TYPE in (ootype.Signed, ootype.Unsigned, rffi.SHORT):
         ilasm.opcode("ldc.i4", str(value))
     elif TYPE in (ootype.SignedLongLong, ootype.UnsignedLongLong):
         ilasm.opcode("ldc.i8", str(value))
     elif TYPE in (ootype.String, ootype.Unicode):
         if value._str is None:
             ilasm.opcode("ldnull")
         else:
             ilasm.opcode("ldstr", string_literal(value._str))
     else:
         assert False, "Unexpected constant type"
Esempio n. 29
0
def ll_math_fmod(x, y):
    # fmod(x, +/-Inf) returns x for finite x.
    if isinf(y) and isfinite(x):
        return x

    _error_reset()
    r = math_fmod(x, y)
    errno = rposix.get_errno()
    if isnan(r):
        if isnan(x) or isnan(y):
            errno = 0
        else:
            errno = EDOM
    if errno:
        _likely_raise(errno, r)
    return r
Esempio n. 30
0
def str__Complex(space, w_complex):
    if w_complex.realval == 0 and copysign(1., w_complex.realval) == 1.:
        return space.wrap(str_format(w_complex.imagval) + 'j')
    sign = (copysign(1., w_complex.imagval) == 1.
            or isnan(w_complex.imagval)) and '+' or ''
    return space.wrap('(' + str_format(w_complex.realval) + sign +
                      str_format(w_complex.imagval) + 'j)')
Esempio n. 31
0
def round(space, number, w_ndigits=0):
    """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 number == 0 or isinf(number) or isnan(number):
        return space.wrap(number)

    # 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(number)
    elif ndigits < NDIGITS_MIN:
        # return 0.0, but with sign of x
        return space.wrap(0.0 * number)

    # finite x, and ndigits is not unreasonably large
    z = round_double(number, ndigits)
    if isinf(z):
        raise OperationError(space.w_OverflowError, space.wrap("rounded value too large to represent"))
    return space.wrap(z)
Esempio n. 32
0
 def push_primitive_constant(self, TYPE, value):
     ilasm = self.ilasm
     if TYPE is ootype.Void:
         pass
     elif TYPE is ootype.Bool:
         ilasm.opcode('ldc.i4', str(int(value)))
     elif TYPE is ootype.Char or TYPE is ootype.UniChar:
         ilasm.opcode('ldc.i4', ord(value))
     elif TYPE is ootype.Float:
         if isinf(value):
             if value < 0.0:
                 ilasm.opcode('ldc.r8', '(00 00 00 00 00 00 f0 ff)')
             else:
                 ilasm.opcode('ldc.r8', '(00 00 00 00 00 00 f0 7f)')
         elif isnan(value):
             ilasm.opcode('ldc.r8', '(00 00 00 00 00 00 f8 ff)')
         else:
             ilasm.opcode('ldc.r8', repr(value))
     elif isinstance(value, CDefinedIntSymbolic):
         ilasm.opcode('ldc.i4', DEFINED_INT_SYMBOLICS[value.expr])
     elif TYPE in (ootype.Signed, ootype.Unsigned, rffi.SHORT):
         ilasm.opcode('ldc.i4', str(value))
     elif TYPE in (ootype.SignedLongLong, ootype.UnsignedLongLong):
         ilasm.opcode('ldc.i8', str(value))
     elif TYPE in (ootype.String, ootype.Unicode):
         if value._str is None:
             ilasm.opcode('ldnull')
         else:
             ilasm.opcode("ldstr", string_literal(value._str))
     else:
         assert False, "Unexpected constant type"
Esempio n. 33
0
 def interp_operations(self, f, args, **kwds):
     # get the JitCodes for the function f
     _get_jitcodes(self, self.CPUClass, f, args, self.type_system, **kwds)
     # try to run it with blackhole.py
     result1 = _run_with_blackhole(self, args)
     # try to run it with pyjitpl.py
     result2 = _run_with_pyjitpl(self, args)
     assert result1 == result2 or isnan(result1) and isnan(result2)
     # try to run it by running the code compiled just before
     result3 = _run_with_machine_code(self, args)
     assert result1 == result3 or result3 == NotImplemented or isnan(result1) and isnan(result3)
     #
     if (longlong.supports_longlong and
         isinstance(result1, longlong.r_float_storage)):
         result1 = longlong.getrealfloat(result1)
     return result1
Esempio n. 34
0
def ll_math_fmod(x, y):
    if isinf(y):
        if isinf(x):
            raise ValueError("math domain error")
        return x  # fmod(x, +/-Inf) returns x for finite x (or if x is a NaN).

    _error_reset()
    r = math_fmod(x, y)
    errno = rposix.get_errno()
    if isnan(r):
        if isnan(x) or isnan(y):
            errno = 0
        else:
            errno = EDOM
    if errno:
        _likely_raise(errno, r)
    return r
Esempio n. 35
0
def ll_math_fmod(x, y):
    if isinf(x) and not isnan(y):
        raise ValueError("math domain error")

    if y == 0:
        raise ValueError("math domain error")

    return math_fmod(x, y)
Esempio n. 36
0
 def interp_operations(self, f, args, **kwds):
     # get the JitCodes for the function f
     _get_jitcodes(self, self.CPUClass, f, args, self.type_system, **kwds)
     # try to run it with blackhole.py
     result1 = _run_with_blackhole(self, args)
     # try to run it with pyjitpl.py
     result2 = _run_with_pyjitpl(self, args)
     assert result1 == result2 or isnan(result1) and isnan(result2)
     # try to run it by running the code compiled just before
     result3 = _run_with_machine_code(self, args)
     assert result1 == result3 or result3 == NotImplemented or isnan(
         result1) and isnan(result3)
     #
     if (longlong.supports_longlong
             and isinstance(result1, longlong.r_float_storage)):
         result1 = longlong.getrealfloat(result1)
     return result1
Esempio n. 37
0
def isfinitejs(ctx, args, this):
    if len(args) < 1:
        return newbool(True)
    n = args[0].ToNumber(ctx)
    if  isinf(n) or isnan(n):
        return newbool(False)
    else:
        return newbool(True)
Esempio n. 38
0
def _erfc(x):
    if rfloat.isnan(x):
        return x
    absx = abs(x)
    if absx < ERF_SERIES_CUTOFF:
        return 1. - _erf_series(x)
    else:
        cf = _erfc_contfrac(absx)
        return cf if x > 0. else 2. - cf
Esempio n. 39
0
def _erfc(x):
    if rfloat.isnan(x):
        return x
    absx = abs(x)
    if absx < ERF_SERIES_CUTOFF:
        return 1. - _erf_series(x)
    else:
        cf = _erfc_contfrac(absx)
        return cf if x > 0. else 2. - cf
Esempio n. 40
0
def compare(ctx, x, y):
    if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber):
        return x.intval > y.intval
    if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber):
        if isnan(x.floatval) or isnan(y.floatval):
            return -1
        return x.floatval > y.floatval
    s1 = x.ToPrimitive(ctx, "Number")
    s2 = y.ToPrimitive(ctx, "Number")
    if not (isinstance(s1, W_String) and isinstance(s2, W_String)):
        s4 = s1.ToNumber(ctx)
        s5 = s2.ToNumber(ctx)
        if isnan(s4) or isnan(s5):
            return False
        return s4 > s5
    else:
        s4 = s1.ToString(ctx)
        s5 = s2.ToString(ctx)
        return s4 > s5
Esempio n. 41
0
def long__Float(space, w_floatobj):
    try:
        return W_LongObject.fromfloat(space, w_floatobj.floatval)
    except OverflowError:
        if isnan(w_floatobj.floatval):
            raise OperationError(
                space.w_ValueError,
                space.wrap("cannot convert float NaN to integer"))
        raise OperationError(space.w_OverflowError,
                             space.wrap("cannot convert float infinity to long"))
Esempio n. 42
0
 def test_random(self):
     # construct a Python float from random integer, using struct
     for _ in xrange(100000):
         Q = random.randrange(2**64)
         x = struct.unpack('<d', struct.pack('<Q', Q))[0]
         # nans are tricky:  we can't hope to reproduce the bit
         # pattern exactly, so check_float will fail for a random nan.
         if isnan(x):
             continue
         self.check_float(x)
Esempio n. 43
0
def floorjs(ctx, args, this):
    if len(args) < 1:
        return W_FloatNumber(NAN)

    val = args[0].ToNumber(ctx)

    pos = math.floor(val)
    if isnan(val):
        pos = INFINITY

    return W_FloatNumber(pos)
Esempio n. 44
0
def long__Float(space, w_floatobj):
    try:
        return W_LongObject.fromfloat(space, w_floatobj.floatval)
    except OverflowError:
        if isnan(w_floatobj.floatval):
            raise OperationError(
                space.w_ValueError,
                space.wrap("cannot convert float NaN to integer"))
        raise OperationError(
            space.w_OverflowError,
            space.wrap("cannot convert float infinity to long"))
Esempio n. 45
0
def test_defined_constant_float():
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.0')
    assert value == 1.0
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.5')
    assert value == 1.5
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.0e20')
    assert value == 1.0e20
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.0e50000')
    assert value == float("inf")
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH (double)0/0')
    assert isnan(value)
Esempio n. 46
0
 def ll_math(x):
     _error_reset()
     r = c_func(x)
     # Error checking fun.  Copied from CPython 2.6
     errno = rposix.get_errno()
     if isnan(r):
         if isnan(x):
             errno = 0
         else:
             errno = EDOM
     elif isinf(r):
         if isinf(x) or isnan(x):
             errno = 0
         elif can_overflow:
             errno = ERANGE
         else:
             errno = EDOM
     if errno:
         _likely_raise(errno, r)
     return r
Esempio n. 47
0
def test_defined_constant_float():
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.0')
    assert value == 1.0
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.5')
    assert value == 1.5
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.0e20')
    assert value == 1.0e20
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.0e50000')
    assert value == float("inf")
    value = rffi_platform.getdefineddouble('BLAH', '#define BLAH (double)0/0')
    assert isnan(value)
Esempio n. 48
0
def format_float(x, code, precision):
    # like float2string, except that the ".0" is not necessary
    if isinf(x):
        if x > 0.0:
            return "inf"
        else:
            return "-inf"
    elif isnan(x):
        return "nan"
    else:
        return formatd(x, code, precision)
Esempio n. 49
0
def format_float(x, code, precision):
    # like float2string, except that the ".0" is not necessary
    if isinf(x):
        if x > 0.0:
            return "inf"
        else:
            return "-inf"
    elif isnan(x):
        return "nan"
    else:
        return formatd(x, code, precision)
Esempio n. 50
0
def name_singlefloat(value, db):
    value = float(value)
    if isinf(value):
        if value > 0:
            return '((float)Py_HUGE_VAL)'
        else:
            return '((float)-Py_HUGE_VAL)'
    elif isnan(value):
        # XXX are these expressions ok?
        return '((float)(Py_HUGE_VAL/Py_HUGE_VAL))'
    else:
        return repr(value) + 'f'
Esempio n. 51
0
def name_float(value, db):
    if isinf(value):
        if value > 0:
            return '(Py_HUGE_VAL)'
        else:
            return '(-Py_HUGE_VAL)'
    elif isnan(value):
        return '(Py_HUGE_VAL/Py_HUGE_VAL)'
    else:
        x = repr(value)
        assert not x.startswith('n')
        return x
Esempio n. 52
0
 def ll_math(x):
     _error_reset()
     r = c_func(x)
     # Error checking fun.  Copied from CPython 2.6
     errno = rposix.get_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
Esempio n. 53
0
def name_float(value, db):
    if isinf(value):
        if value > 0:
            return '(Py_HUGE_VAL)'
        else:
            return '(-Py_HUGE_VAL)'
    elif isnan(value):
        return '(Py_HUGE_VAL/Py_HUGE_VAL)'
    else:
        x = repr(value)
        assert not x.startswith('n')
        return x
Esempio n. 54
0
def _gamma(x):
    if rfloat.isnan(x) or (rfloat.isinf(x) and x > 0.):
        return x
    if rfloat.isinf(x):
        raise ValueError("math domain error")
    if x == 0.:
        raise ValueError("math domain error")
    if x == math.floor(x):
        if x < 0.:
            raise ValueError("math domain error")
        if x < len(_gamma_integrals):
            return _gamma_integrals[int(x) - 1]
    absx = abs(x)
    if absx < 1e-20:
        r = 1. / x
        if rfloat.isinf(r):
            raise OverflowError("math range error")
        return r
    if absx > 200.:
        if x < 0.:
            return 0. / -_sinpi(x)
        else:
            raise OverflowError("math range error")
    y = absx + _lanczos_g_minus_half
    if absx > _lanczos_g_minus_half:
        q = y - absx
        z = q - _lanczos_g_minus_half
    else:
        q = y - _lanczos_g_minus_half
        z = q - absx
    z = z * _lanczos_g / y
    if x < 0.:
        r = -math.pi / _sinpi(absx) / absx * math.exp(y) / _lanczos_sum(absx)
        r -= z * r
        if absx < 140.:
            r /= math.pow(y, absx - .5)
        else:
            sqrtpow = math.pow(y, absx / 2. - .25)
            r /= sqrtpow
            r /= sqrtpow
    else:
        r = _lanczos_sum(absx) / math.exp(y)
        r += z * r
        if absx < 140.:
            r *= math.pow(y, absx - .5)
        else:
            sqrtpow = math.pow(y, absx / 2. - .25)
            r *= sqrtpow
            r *= sqrtpow
    if rfloat.isinf(r):
        raise OverflowError("math range error")
    return r
Esempio n. 55
0
 def _push_double_constant(self, value):
     if isnan(value):
         jvm.DOUBLENAN.load(self)
     elif isinf(value):
         if value > 0: jvm.DOUBLEPOSINF.load(self)
         else: jvm.DOUBLENEGINF.load(self)
     elif value == 0.0:
         self.emit(jvm.DCONST_0)
     elif value == 1.0:
         self.emit(jvm.DCONST_1)
     else:
         # Big hack to avoid exponential notation:
         self.emit(jvm.LDC2, "%22.22f" % value)
Esempio n. 56
0
def c_phase(x, y):
    # Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't
    # follow C99 for atan2(0., 0.).
    if isnan(x) or isnan(y):
        return NAN
    if isinf(y):
        if isinf(x):
            if copysign(1., x) == 1.:
                # atan2(+-inf, +inf) == +-pi/4
                return copysign(0.25 * math.pi, y)
            else:
                # atan2(+-inf, -inf) == +-pi*3/4
                return copysign(0.75 * math.pi, y)
        # atan2(+-inf, x) == +-pi/2 for finite x
        return copysign(0.5 * math.pi, y)
    if isinf(x) or y == 0.:
        if copysign(1., x) == 1.:
            # atan2(+-y, +inf) = atan2(+-0, +x) = +-0.
            return copysign(0., y)
        else:
            # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi.
            return copysign(math.pi, y)
    return math.atan2(y, x)
Esempio n. 57
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 rfloat.isinf(v) or rfloat.isnan(v):
                if (not rfloat.isinf(original) and not rfloat.isnan(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)
Esempio n. 58
0
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)

    _error_reset()
    r = math_hypot(x, y)
    errno = rposix.get_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