Пример #1
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)
Пример #2
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)
Пример #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)
Пример #4
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)
Пример #5
0
def division(ctx, nleft, nright):
    fleft = nleft.ToNumber()
    fright = nright.ToNumber()
    if isnan(fleft) or isnan(fright):
        return w_NAN

    if isinf(fleft) and isinf(fright):
        return w_NAN

    if isinf(fleft) and fright == 0:
        s = sign_of(fleft, fright)
        return w_signed_inf(s)

    if isinf(fright):
        return _w(0)

    if fleft == 0 and fright == 0:
        return w_NAN

    if fright == 0:
        s = sign_of(fleft, fright)
        return w_signed_inf(s)

    val = fleft / fright
    return W_FloatNumber(val)
Пример #6
0
 def check_roundtrip(x, size):
     s = c_pack(x, size)
     assert s == pack(x, size)
     if not isnan(x):
         assert unpack(s) == x
         assert c_unpack(s) == x
     else:
         assert isnan(unpack(s))
         assert isnan(c_unpack(s))
Пример #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
Пример #8
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

    r = math_pow(x, y)
    errno = rposix.get_saved_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
Пример #9
0
def js_atan2(this, args):
    arg0 = get_arg(args, 0)
    arg1 = get_arg(args, 1)
    y = arg0.ToNumber()
    x = arg1.ToNumber()

    if isnan(x) or isnan(y):
        return NAN

    return math.atan2(y, x)
Пример #10
0
def js_atan2(this, args):
    arg0 = get_arg(args, 0)
    arg1 = get_arg(args, 1)
    y = arg0.ToNumber()
    x = arg1.ToNumber()

    if isnan(x) or isnan(y):
        return NAN

    return math.atan2(y, x)
Пример #11
0
 def check_roundtrip(x, size):
     s = c_pack(x, size)
     if not isnan(x):
         # pack uses copysign which is ambiguous for NAN
         assert s == pack(x, size)
         assert unpack(s) == x
         assert c_unpack(s) == x
     else:
         assert isnan(unpack(s))
         assert isnan(c_unpack(s))
Пример #12
0
 def check_roundtrip(x, size):
     s = c_pack(x, size)
     if not isnan(x):
         # pack uses copysign which is ambiguous for NAN
         assert s == pack(x, size)
         assert unpack(s) == x
         assert c_unpack(s) == x
     else:
         assert isnan(unpack(s))
         assert isnan(c_unpack(s))
Пример #13
0
def js_pow(this, args):
    w_x = get_arg(args, 0)
    w_y = get_arg(args, 1)
    x = w_x.ToNumber()
    y = w_y.ToNumber()

    if isnan(y):
        return NAN
    if y == 0:
        return 1
    if isnan(x):
        return NAN
    if abs(x) > 1 and y == INFINITY:
        return INFINITY
    if abs(x) > 1 and y == -INFINITY:
        return 0
    if abs(x) == 1 and isinf(y):
        return NAN
    if abs(x) < 1 and y == INFINITY:
        return 0
    if abs(x) < 1 and y == -INFINITY:
        return INFINITY
    if x == INFINITY and y > 0:
        return INFINITY
    if x == INFINITY and y < 0:
        return 0
    if x == -INFINITY and y > 0 and isodd(y):
        return -INFINITY
    if x == -INFINITY and y > 0 and not isodd(y):
        return INFINITY
    if x == -INFINITY and y < 0 and isodd(y):
        return -0.0
    if x == -INFINITY and y < 0 and not isodd(y):
        return 0
    if eq_signed_zero(x, 0.0) and y > 0:
        return 0
    if eq_signed_zero(x, 0.0) and y < 0:
        return INFINITY
    if eq_signed_zero(x, -0.0) and y > 0 and isodd(y):
        return -0.0
    if eq_signed_zero(x, -0.0) and y > 0 and not isodd(y):
        return +0
    if eq_signed_zero(x, -0.0) and y < 0 and isodd(y):
        return -INFINITY
    if eq_signed_zero(x, -0.0) and y < 0 and not isodd(y):
        return INFINITY
    if x < 0 and not isinstance(y, int):
        return NAN

    try:
        return math.pow(x, y)
    except OverflowError:
        return INFINITY
Пример #14
0
 def __eq__(self, other):
     if (type(self) is SomeFloat and type(other) is SomeFloat and
         self.is_constant() and other.is_constant()):
         from rpython.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)
Пример #15
0
 def __eq__(self, other):
     if (type(self) is SomeFloat and type(other) is SomeFloat
             and self.is_constant() and other.is_constant()):
         from rpython.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)
Пример #16
0
def js_pow(this, args):
    w_x = get_arg(args, 0)
    w_y = get_arg(args, 1)
    x = w_x.ToNumber()
    y = w_y.ToNumber()

    if isnan(y):
        return NAN
    if y == 0:
        return 1
    if isnan(x):
        return NAN
    if abs(x) > 1 and y == INFINITY:
        return INFINITY
    if abs(x) > 1 and y == -INFINITY:
        return 0
    if abs(x) == 1 and isinf(y):
        return NAN
    if abs(x) < 1 and y == INFINITY:
        return 0
    if abs(x) < 1 and y == -INFINITY:
        return INFINITY
    if x == INFINITY and y > 0:
        return INFINITY
    if x == INFINITY and y < 0:
        return 0
    if x == -INFINITY and y > 0 and isodd(y):
        return -INFINITY
    if x == -INFINITY and y > 0 and not isodd(y):
        return INFINITY
    if x == -INFINITY and y < 0 and isodd(y):
        return -0.0
    if x == -INFINITY and y < 0 and not isodd(y):
        return 0
    if eq_signed_zero(x, 0.0) and y > 0:
        return 0
    if eq_signed_zero(x, 0.0) and y < 0:
        return INFINITY
    if eq_signed_zero(x, -0.0) and y > 0 and isodd(y):
        return -0.0
    if eq_signed_zero(x, -0.0) and y > 0 and not isodd(y):
        return +0
    if eq_signed_zero(x, -0.0) and y < 0 and isodd(y):
        return -INFINITY
    if eq_signed_zero(x, -0.0) and y < 0 and not isodd(y):
        return INFINITY
    if x < 0 and not isinstance(y, int):
        return NAN

    try:
        return math.pow(x, y)
    except OverflowError:
        return INFINITY
Пример #17
0
def rAlmostEqual(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 True,''
        raise AssertionError(msg + '%r should be nan' % (b,))

    if isinf(a):
        if a == b:
            return True,''
        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 True,''
    raise AssertionError(msg + \
            '%r and %r are not sufficiently close, %g > %g' %\
            (a, b, absolute_error, max(abs_err, rel_err*abs(a))))
Пример #18
0
def rAlmostEqual(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 True, ''
        raise AssertionError(msg + '%r should be nan' % (b, ))

    if isinf(a):
        if a == b:
            return True, ''
        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 True, ''
    raise AssertionError(msg + \
            '%r and %r are not sufficiently close, %g > %g' %\
            (a, b, absolute_error, max(abs_err, rel_err*abs(a))))
Пример #19
0
 def interp_operations(self, f, args, **kwds):
     # get the JitCodes for the function f
     _get_jitcodes(self, self.CPUClass, f, args, **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
Пример #20
0
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
Пример #21
0
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
Пример #22
0
 def ovfcheck_float_to_int(x):
     from rpython.rlib.rfloat import isnan
     if isnan(x):
         raise OverflowError
     if -2147483649.0 < x < 2147483648.0:
         return int(x)
     raise OverflowError
Пример #23
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"
Пример #24
0
 def descr_repr(self, space):
     if self.realval == 0 and copysign(1., self.realval) == 1.:
         return space.newtext(repr_format(self.imagval) + 'j')
     sign = (copysign(1., self.imagval) == 1.
             or isnan(self.imagval)) and '+' or ''
     return space.newtext('(' + repr_format(self.realval) + sign +
                          repr_format(self.imagval) + 'j)')
Пример #25
0
def test_nan_and_special_values():
    from rpython.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)
Пример #26
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)
Пример #27
0
 def ovfcheck_float_to_int(x):
     from rpython.rlib.rfloat import isnan
     if isnan(x):
         raise OverflowError
     if -2147483649.0 < x < 2147483648.0:
         return int(x)
     raise OverflowError
Пример #28
0
def ovfcheck_float_to_longlong(x):
    from rpython.rlib.rfloat import isnan
    if isnan(x):
        raise OverflowError
    if -9223372036854776832.0 <= x < 9223372036854775296.0:
        return r_longlong(x)
    raise OverflowError
Пример #29
0
 def var_dump(self, space, indent, recursion):
     if isinf(self.floatval):
         inf = "%s" % self.floatval
         return "%sfloat(%s)\n" % (indent, inf.upper())
     if isnan(self.floatval):
         return "%sfloat(NAN)\n" % (indent, )
     return "%sfloat(%s)\n" % (indent, self.str(space))
Пример #30
0
 def ovfcheck_float_to_int(x):
     from rpython.rlib.rfloat import isnan
     if isnan(x):
         raise OverflowError
     if -9223372036854776832.0 <= x < 9223372036854775296.0:
         return int(x)
     raise OverflowError
Пример #31
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
Пример #32
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 number == 0 or isinf(number) or isnan(number):
        return space.newfloat(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.newfloat(number)
    elif ndigits < NDIGITS_MIN:
        # return 0.0, but with sign of x
        return space.newfloat(0.0 * number)

    # 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)
Пример #33
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
Пример #34
0
def c_div(x, y): #x/y
    (r1, i1), (r2, i2) = x, y
    if r2 < 0:
        abs_r2 = -r2
    else:
        abs_r2 = r2
    if i2 < 0:
        abs_i2 = -i2
    else:
        abs_i2 = i2
    if abs_r2 >= abs_i2:
        if abs_r2 == 0.0:
            raise ZeroDivisionError
        else:
            ratio = i2 / r2
            denom = r2 + i2 * ratio
            rr = (r1 + i1 * ratio) / denom
            ir = (i1 - r1 * ratio) / denom
    elif isnan(r2):
        rr = NAN
        ir = NAN
    else:
        ratio = r2 / i2
        denom = r2 * ratio + i2
        assert i2 != 0.0
        rr = (r1 * ratio + i1) / denom
        ir = (i1 * ratio - r1) / denom
    return (rr, ir)
Пример #35
0
 def descr_str(self, space):
     if self.realval == 0 and copysign(1., self.realval) == 1.:
         return space.wrap(str_format(self.imagval) + 'j')
     sign = (copysign(1., self.imagval) == 1.
             or isnan(self.imagval)) and '+' or ''
     return space.wrap('(' + str_format(self.realval) + sign +
                       str_format(self.imagval) + 'j)')
Пример #36
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 rfloat.isinf(x):
        mant = r_ulonglong(0)
        exp = MAX_EXP - MIN_EXP + 2
    elif rfloat.isnan(x):  # rfloat.isnan(x):
        asint = cast(ULONGLONG, float2longlong(x))
        mant = asint & ((r_ulonglong(1) << 51) - 1)
        if mant == 0:
            mant = r_ulonglong(1) << (MANT_DIG - 1) - 1
        sign = asint < 0
        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")

        mant = mant << 1
    # 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
    exp = r_ulonglong(exp)
    sign = r_ulonglong(sign)
    return (mant, (sign << BITS - MANT_DIG - 1) | exp)
Пример #37
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
Пример #38
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"
Пример #39
0
def fn_encode_nan(f1, i2):
    from rpython.rlib.longlong2float import can_encode_float, can_encode_int32
    from rpython.rlib.longlong2float import encode_int32_into_longlong_nan
    from rpython.rlib.longlong2float import decode_int32_from_longlong_nan
    from rpython.rlib.longlong2float import is_int32_from_longlong_nan
    from rpython.rlib.rfloat import isnan
    assert can_encode_float(f1)
    assert can_encode_int32(i2)
    l1 = float2longlong(f1)
    l2 = encode_int32_into_longlong_nan(i2)
    assert not is_int32_from_longlong_nan(l1)
    assert is_int32_from_longlong_nan(l2)
    f1b = longlong2float(l1)
    assert f1b == f1 or (isnan(f1b) and isnan(f1))
    assert decode_int32_from_longlong_nan(l2) == i2
    return 42
Пример #40
0
def test_primitive_log_n():
    assert prim(primitives.FLOAT_LOG_N, [1.0]).value == 0.0
    assert prim(primitives.FLOAT_LOG_N, [math.e]).value == 1.0
    assert float_equals(prim(primitives.FLOAT_LOG_N, [10.0]), math.log(10))
    assert isinf(prim(primitives.FLOAT_LOG_N,
                      [0.0]).value)  # works also for negative infinity
    assert isnan(prim(primitives.FLOAT_LOG_N, [-1.0]).value)
Пример #41
0
def c_div(x, y):  #x/y
    (r1, i1), (r2, i2) = x, y
    if r2 < 0:
        abs_r2 = -r2
    else:
        abs_r2 = r2
    if i2 < 0:
        abs_i2 = -i2
    else:
        abs_i2 = i2
    if abs_r2 >= abs_i2:
        if abs_r2 == 0.0:
            raise ZeroDivisionError
        else:
            ratio = i2 / r2
            denom = r2 + i2 * ratio
            rr = (r1 + i1 * ratio) / denom
            ir = (i1 - r1 * ratio) / denom
    elif isnan(r2):
        rr = NAN
        ir = NAN
    else:
        ratio = r2 / i2
        denom = r2 * ratio + i2
        assert i2 != 0.0
        rr = (r1 * ratio + i1) / denom
        ir = (i1 * ratio - r1) / denom
    return (rr, ir)
Пример #42
0
def last_index_of(this, args):
    search_string = get_arg(args, 0)
    position = get_arg(args, 1)

    s = this.to_string()
    search_str = search_string.to_string()
    num_pos = position.ToNumber()

    from rpython.rlib.rfloat import INFINITY, isnan, isinf

    if isnan(num_pos):
        pos = INFINITY
    elif isinf(num_pos):
        pos = num_pos
    else:
        pos = int(num_pos)

    length = len(s)
    start = min(max(pos, 0), length)
    search_len = len(search_str)

    if isinf(start):
        idx = s.rfind(search_str)
        return idx

    end = int(start + search_len)
    assert end >= 0
    idx = s.rfind(search_str, 0, end)
    return idx
Пример #43
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
Пример #44
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
Пример #45
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 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 oefmt(space.w_OverflowError,
                    "rounded value too large to represent")
    return space.wrap(z)
Пример #46
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)
Пример #47
0
def fn_encode_nan(f1, i2):
    from rpython.rlib.longlong2float import can_encode_float, can_encode_int32
    from rpython.rlib.longlong2float import encode_int32_into_longlong_nan
    from rpython.rlib.longlong2float import decode_int32_from_longlong_nan
    from rpython.rlib.longlong2float import is_int32_from_longlong_nan
    from rpython.rlib.rfloat import isnan
    assert can_encode_float(f1)
    assert can_encode_int32(i2)
    l1 = float2longlong(f1)
    l2 = encode_int32_into_longlong_nan(i2)
    assert not is_int32_from_longlong_nan(l1)
    assert is_int32_from_longlong_nan(l2)
    f1b = longlong2float(l1)
    assert f1b == f1 or (isnan(f1b) and isnan(f1))
    assert decode_int32_from_longlong_nan(l2) == i2
    return 42
Пример #48
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
Пример #49
0
 def var_dump(self, space, indent, recursion):
     if isinf(self.floatval):
         inf = "%s" % self.floatval
         return "%sfloat(%s)\n" % (indent, inf.upper())
     if isnan(self.floatval):
         return "%sfloat(NAN)\n" % (indent,)
     return "%sfloat(%s)\n" % (indent, self.str(space))
Пример #50
0
 def descr_str(self, space):
     if self.realval == 0 and copysign(1., self.realval) == 1.:
         return space.wrap(str_format(self.imagval) + 'j')
     sign = (copysign(1., self.imagval) == 1. or
             isnan(self.imagval)) and '+' or ''
     return space.wrap('(' + str_format(self.realval)
                       + sign + str_format(self.imagval) + 'j)')
Пример #51
0
def last_index_of(this, args):
    search_string = get_arg(args, 0)
    position = get_arg(args, 1)

    s = this.to_string()
    search_str = search_string.to_string()
    num_pos = position.ToNumber()

    from rpython.rlib.rfloat import INFINITY, isnan, isinf

    if isnan(num_pos):
        pos = INFINITY
    elif isinf(num_pos):
        pos = num_pos
    else:
        pos = int(num_pos)

    length = len(s)
    start = min(max(pos, 0), length)
    search_len = len(search_str)

    if isinf(start):
        idx = s.rfind(search_str)
        return idx

    end = int(start + search_len)
    assert end >= 0
    idx = s.rfind(search_str, 0, end)
    return idx
Пример #52
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 rfloat.isinf(x):
        mant = r_ulonglong(0)
        exp = MAX_EXP - MIN_EXP + 2
    elif rfloat.isnan(x):  # rfloat.isnan(x):
        asint = cast(ULONGLONG, float2longlong(x))
        mant = asint & ((r_ulonglong(1) << 51) - 1)
        if mant == 0:
            mant = r_ulonglong(1) << (MANT_DIG - 1) - 1
        sign = asint < 0
        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")

        mant = mant << 1
    # 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
    exp = r_ulonglong(exp)
    sign = r_ulonglong(sign)
    return (mant, (sign << BITS - MANT_DIG - 1) | exp)
Пример #53
0
    def ToInteger(self):
        if isnan(self._floatval_):
            return 0

        if self._floatval_ == 0 or isinf(self._floatval_):
            return int(self._floatval_)

        return intmask(int(self._floatval_))
Пример #54
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)
Пример #55
0
 def var_export(self, space, indent, recursion, suffix):
     if isinf(self.floatval):
         inf = "%s" % self.floatval
         return "%s" % inf.upper()
     if isnan(self.floatval):
         return "NAN"
     out = "%s%s%s" % (indent, self.str(space), suffix)
     return out
Пример #56
0
def js_cos(this, args):
    arg0 = get_arg(args, 0)
    x = arg0.ToNumber()

    if isnan(x) or isinf(x):
        return NAN

    return math.cos(x)
Пример #57
0
def js_abs(this, args):
    arg0 = get_arg(args, 0)
    x = arg0.ToNumber()

    if isnan(x):
        return NAN

    return abs(x)