Example #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)
Example #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)
Example #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)
Example #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)
Example #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)
Example #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))
Example #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
Example #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
Example #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)
Example #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)
Example #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))
Example #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))
Example #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
Example #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)
Example #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)
Example #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
Example #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))))
Example #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))))
Example #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
Example #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
Example #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
Example #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
Example #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"
Example #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)')
Example #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)
Example #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)
Example #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
Example #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
Example #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))
Example #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
Example #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
Example #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)
Example #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
Example #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)
Example #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)')
Example #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)
Example #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
Example #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"
Example #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
Example #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)
Example #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)
Example #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
Example #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
Example #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
Example #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)
Example #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)
Example #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
Example #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
Example #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))
Example #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)')
Example #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
Example #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)
Example #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_))
Example #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)
Example #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
Example #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)
Example #57
0
def js_abs(this, args):
    arg0 = get_arg(args, 0)
    x = arg0.ToNumber()

    if isnan(x):
        return NAN

    return abs(x)