Пример #1
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
Пример #2
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
Пример #3
0
def float_hex__Float(space, w_float):
    value = w_float.floatval
    if not isfinite(value):
        return str__Float(space, w_float)
    if value == 0.0:
        if copysign(1., value) == -1.:
            return space.wrap("-0x0.0p+0")
        else:
            return space.wrap("0x0.0p+0")
    mant, exp = math.frexp(value)
    shift = 1 - max(rfloat.DBL_MIN_EXP - exp, 0)
    mant = math.ldexp(mant, shift)
    mant = abs(mant)
    exp -= shift
    result = ['\0'] * ((TOHEX_NBITS - 1) // 4 + 2)
    result[0] = _char_from_hex(int(mant))
    mant -= int(mant)
    result[1] = "."
    for i in range((TOHEX_NBITS - 1) // 4):
        mant *= 16.0
        result[i + 2] = _char_from_hex(int(mant))
        mant -= int(mant)
    if exp < 0:
        sign = "-"
    else:
        sign = "+"
    exp = abs(exp)
    s = ''.join(result)
    if value < 0.0:
        return space.wrap("-0x%sp%s%d" % (s, sign, exp))
    else:
        return space.wrap("0x%sp%s%d" % (s, sign, exp))
Пример #4
0
Файл: node.py Проект: njues/Sypy
def generic_initializationexpr(db, value, access_expr, decoration):
    if isinstance(typeOf(value), ContainerType):
        node = db.getcontainernode(value)
        lines = list(node.initializationexpr(decoration + '.'))
        lines[-1] += ','
        return lines
    else:
        comma = ','
        if typeOf(value) == Ptr(PyObject) and value:
            # cannot just write 'gxxx' as a constant in a structure :-(
            node = db.getcontainernode(value._obj)
            expr = 'NULL /*%s*/' % node.name
            node.where_to_copy_me.append('&%s' % access_expr)
        elif typeOf(value) == Float and not isfinite(value):
            db.late_initializations.append(('%s' % access_expr, db.get(value)))
            expr = '0.0 /* patched later by %sinfinity */' % ('-+'[value > 0])
        else:
            expr = db.get(value)
            if typeOf(value) is Void:
                comma = ''
        expr += comma
        i = expr.find('\n')
        if i < 0: i = len(expr)
        expr = '%s\t/* %s */%s' % (expr[:i], decoration, expr[i:])
        return expr.split('\n')
Пример #5
0
def generic_initializationexpr(db, value, access_expr, decoration):
    if isinstance(typeOf(value), ContainerType):
        node = db.getcontainernode(value)
        lines = list(node.initializationexpr(decoration + "."))
        lines[-1] += ","
        return lines
    else:
        comma = ","
        if typeOf(value) == Ptr(PyObject) and value:
            # cannot just write 'gxxx' as a constant in a structure :-(
            node = db.getcontainernode(value._obj)
            expr = "NULL /*%s*/" % node.name
            node.where_to_copy_me.append("&%s" % access_expr)
        elif typeOf(value) == Float and not isfinite(value):
            db.late_initializations.append(("%s" % access_expr, db.get(value)))
            expr = "0.0 /* patched later by %sinfinity */" % ("-+"[value > 0])
        else:
            expr = db.get(value)
            if typeOf(value) is Void:
                comma = ""
        expr += comma
        i = expr.find("\n")
        if i < 0:
            i = len(expr)
        expr = "%s\t/* %s */%s" % (expr[:i], decoration, expr[i:])
        return expr.split("\n")
Пример #6
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)
Пример #7
0
def float_hex__Float(space, w_float):
    value = w_float.floatval
    if not isfinite(value):
        return str__Float(space, w_float)
    if value == 0.0:
        if copysign(1., value) == -1.:
            return space.wrap("-0x0.0p+0")
        else:
            return space.wrap("0x0.0p+0")
    mant, exp = math.frexp(value)
    shift = 1 - max(rfloat.DBL_MIN_EXP - exp, 0)
    mant = math.ldexp(mant, shift)
    mant = abs(mant)
    exp -= shift
    result = ['\0'] * ((TOHEX_NBITS - 1) // 4 + 2)
    result[0] = _char_from_hex(int(mant))
    mant -= int(mant)
    result[1] = "."
    for i in range((TOHEX_NBITS - 1) // 4):
        mant *= 16.0
        result[i + 2] = _char_from_hex(int(mant))
        mant -= int(mant)
    if exp < 0:
        sign = "-"
    else:
        sign = "+"
    exp = abs(exp)
    s = ''.join(result)
    if value < 0.0:
        return space.wrap("-0x%sp%s%d" % (s, sign, exp))
    else:
        return space.wrap("0x%sp%s%d" % (s, sign, exp))
Пример #8
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)
Пример #9
0
def ll_math_sqrt(x):
    if x < 0.0:
        raise ValueError, "math domain error"

    if isfinite(x):
        return sqrt_nonneg(x)

    return x  # +inf or nan
Пример #10
0
def ll_math_sqrt(x):
    if x < 0.0:
        raise ValueError, "math domain error"

    if isfinite(x):
        return sqrt_nonneg(x)

    return x   # +inf or nan
Пример #11
0
 def do_compare_bigint(f1, b2):
     """f1 is a float.  b2 is a bigint."""
     if not isfinite(f1) or math.floor(f1) != f1:
         return opname == 'ne'
     b1 = rbigint.fromfloat(f1)
     res = b1.eq(b2)
     if opname == 'ne':
         res = not res
     return res
Пример #12
0
 def do_compare_bigint(f1, b2):
     """f1 is a float.  b2 is a bigint."""
     if not isfinite(f1) or math.floor(f1) != f1:
         return opname == 'ne'
     b1 = rbigint.fromfloat(f1)
     res = b1.eq(b2)
     if opname == 'ne':
         res = not res
     return res
Пример #13
0
 def ll_math(x):
     _error_reset()
     r = c_func(x)
     # Error checking fun.  Copied from CPython 2.6
     errno = rposix.get_errno()
     if not isfinite(r):
         if isnan(r):
             if isnan(x):
                 errno = 0
             else:
                 errno = EDOM
         else:  # isinf(r)
             if not isfinite(x):
                 errno = 0
             elif can_overflow:
                 errno = ERANGE
             else:
                 errno = EDOM
     if errno:
         _likely_raise(errno, r)
     return r
Пример #14
0
 def ll_math(x):
     _error_reset()
     r = c_func(x)
     # Error checking fun.  Copied from CPython 2.6
     errno = rposix.get_errno()
     if not isfinite(r):
         if isnan(r):
             if isnan(x):
                 errno = 0
             else:
                 errno = EDOM
         else:  # isinf(r)
             if not isfinite(x):
                 errno = 0
             elif can_overflow:
                 errno = ERANGE
             else:
                 errno = EDOM
     if errno:
         _likely_raise(errno, r)
     return r
Пример #15
0
def float2string(x, code, precision):
    # we special-case explicitly inf and nan here
    if isfinite(x):
        s = formatd(x, code, precision, DTSF_ADD_DOT_0)
    elif isinf(x):
        if x > 0.0:
            s = "inf"
        else:
            s = "-inf"
    else:  # isnan(x):
        s = "nan"
    return s
Пример #16
0
def float2string(x, code, precision):
    # we special-case explicitly inf and nan here
    if isfinite(x):
        s = formatd(x, code, precision, DTSF_ADD_DOT_0)
    elif isinf(x):
        if x > 0.0:
            s = "inf"
        else:
            s = "-inf"
    else:  # isnan(x):
        s = "nan"
    return s
Пример #17
0
def ll_math_frexp(x):
    # deal with special cases directly, to sidestep platform differences
    if not isfinite(x) or not x:
        mantissa = x
        exponent = 0
    else:
        exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
        try:
            mantissa = math_frexp(x, exp_p)
            exponent = rffi.cast(lltype.Signed, exp_p[0])
        finally:
            lltype.free(exp_p, flavor='raw')
    return (mantissa, exponent)
Пример #18
0
def ll_math_frexp(x):
    # deal with special cases directly, to sidestep platform differences
    if not isfinite(x) or not x:
        mantissa = x
        exponent = 0
    else:
        exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
        try:
            mantissa = math_frexp(x, exp_p)
            exponent = rffi.cast(lltype.Signed, exp_p[0])
        finally:
            lltype.free(exp_p, flavor='raw')
    return (mantissa, exponent)
Пример #19
0
 def do_compare_bigint(f1, b2):
     """f1 is a float.  b2 is a bigint."""
     if not isfinite(f1):
         return op(f1, 0.0)
     if opname == 'gt' or opname == 'le':
         # 'float > long'   <==>  'ceil(float) > long'
         # 'float <= long'  <==>  'ceil(float) <= long'
         f1 = math.ceil(f1)
     else:
         # 'float < long'   <==>  'floor(float) < long'
         # 'float >= long'  <==>  'floor(float) >= long'
         f1 = math.floor(f1)
     b1 = rbigint.fromfloat(f1)
     return getattr(b1, opname)(b2)
Пример #20
0
 def do_compare_bigint(f1, b2):
     """f1 is a float.  b2 is a bigint."""
     if not isfinite(f1):
         return op(f1, 0.0)
     if opname == 'gt' or opname == 'le':
         # 'float > long'   <==>  'ceil(float) > long'
         # 'float <= long'  <==>  'ceil(float) <= long'
         f1 = math.ceil(f1)
     else:
         # 'float < long'   <==>  'floor(float) < long'
         # 'float >= long'  <==>  'floor(float) >= long'
         f1 = math.floor(f1)
     b1 = rbigint.fromfloat(f1)
     return getattr(b1, opname)(b2)
Пример #21
0
def ll_math_hypot(x, y):
    # hypot(x, +/-Inf) returns Inf, even if x is a NaN.
    if isinf(x):
        return math_fabs(x)
    if isinf(y):
        return math_fabs(y)

    _error_reset()
    r = math_hypot(x, y)
    errno = rposix.get_errno()
    if not isfinite(r):
        if isnan(r):
            if isnan(x) or isnan(y):
                errno = 0
            else:
                errno = EDOM
        else:  # isinf(r)
            if isfinite(x) and isfinite(y):
                errno = ERANGE
            else:
                errno = 0
    if errno:
        _likely_raise(errno, r)
    return r
Пример #22
0
def ll_math_modf(x):
    # some platforms don't do the right thing for NaNs and
    # infinities, so we take care of special cases directly.
    if not isfinite(x):
        if isnan(x):
            return (x, x)
        else:  # isinf(x)
            return (math_copysign(0.0, x), x)
    intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw')
    try:
        fracpart = math_modf(x, intpart_p)
        intpart = intpart_p[0]
    finally:
        lltype.free(intpart_p, flavor='raw')
    return (fracpart, intpart)
Пример #23
0
def ll_math_hypot(x, y):
    # hypot(x, +/-Inf) returns Inf, even if x is a NaN.
    if isinf(x):
        return math_fabs(x)
    if isinf(y):
        return math_fabs(y)

    _error_reset()
    r = math_hypot(x, y)
    errno = rposix.get_errno()
    if not isfinite(r):
        if isnan(r):
            if isnan(x) or isnan(y):
                errno = 0
            else:
                errno = EDOM
        else:  # isinf(r)
            if isfinite(x) and isfinite(y):
                errno = ERANGE
            else:
                errno = 0
    if errno:
        _likely_raise(errno, r)
    return r
Пример #24
0
def ll_math_modf(x):
    # some platforms don't do the right thing for NaNs and
    # infinities, so we take care of special cases directly.
    if not isfinite(x):
        if isnan(x):
            return (x, x)
        else:   # isinf(x)
            return (math_copysign(0.0, x), x)
    intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw')
    try:
        fracpart = math_modf(x, intpart_p)
        intpart = intpart_p[0]
    finally:
        lltype.free(intpart_p, flavor='raw')
    return (fracpart, intpart)
Пример #25
0
def ll_math_fmod(x, y):
    # fmod(x, +/-Inf) returns x for finite x.
    if isinf(y) and isfinite(x):
        return x

    _error_reset()
    r = math_fmod(x, y)
    errno = rposix.get_errno()
    if isnan(r):
        if isnan(x) or isnan(y):
            errno = 0
        else:
            errno = EDOM
    if errno:
        _likely_raise(errno, r)
    return r
Пример #26
0
def ll_math_fmod(x, y):
    # fmod(x, +/-Inf) returns x for finite x.
    if isinf(y) and isfinite(x):
        return x

    _error_reset()
    r = math_fmod(x, y)
    errno = rposix.get_errno()
    if isnan(r):
        if isnan(x) or isnan(y):
            errno = 0
        else:
            errno = EDOM
    if errno:
        _likely_raise(errno, r)
    return r
Пример #27
0
def ll_math_ldexp(x, exp):
    if x == 0.0 or not isfinite(x):
        return x    # NaNs, zeros and infinities are returned unchanged
    if exp > INT_MAX:
        # overflow (64-bit platforms only)
        r = math_copysign(INFINITY, x)
        errno = ERANGE
    elif exp < INT_MIN:
        # underflow to +-0 (64-bit platforms only)
        r = math_copysign(0.0, x)
        errno = 0
    else:
        _error_reset()
        r = math_ldexp(x, exp)
        errno = rposix.get_errno()
        if isinf(r):
            errno = ERANGE
    if errno:
        _likely_raise(errno, r)
    return r
Пример #28
0
def ll_math_ldexp(x, exp):
    if x == 0.0 or not isfinite(x):
        return x  # NaNs, zeros and infinities are returned unchanged
    if exp > INT_MAX:
        # overflow (64-bit platforms only)
        r = math_copysign(INFINITY, x)
        errno = ERANGE
    elif exp < INT_MIN:
        # underflow to +-0 (64-bit platforms only)
        r = math_copysign(0.0, x)
        errno = 0
    else:
        _error_reset()
        r = math_ldexp(x, exp)
        errno = rposix.get_errno()
        if isinf(r):
            errno = ERANGE
    if errno:
        _likely_raise(errno, r)
    return r
Пример #29
0
def _hash_float(f):
    """The algorithm behind compute_hash() for a float.
    This implementation is identical to the CPython implementation,
    except the fact that the integer case is not treated specially.
    In RPython, floats cannot be used with ints in dicts, anyway.
    """
    from pypy.rlib.rarithmetic import intmask
    from pypy.rlib.rfloat import isfinite, isinf
    if not isfinite(f):
        if isinf(f):
            if f < 0.0:
                return -271828
            else:
                return 314159
        else: #isnan(f):
            return 0
    v, expo = math.frexp(f)
    v *= TAKE_NEXT
    hipart = int(v)
    v = (v - float(hipart)) * TAKE_NEXT
    x = hipart + int(v) + (expo << 15)
    return intmask(x)
Пример #30
0
def _hash_float(f):
    """The algorithm behind compute_hash() for a float.
    This implementation is identical to the CPython implementation,
    except the fact that the integer case is not treated specially.
    In RPython, floats cannot be used with ints in dicts, anyway.
    """
    from pypy.rlib.rarithmetic import intmask
    from pypy.rlib.rfloat import isfinite, isinf
    if not isfinite(f):
        if isinf(f):
            if f < 0.0:
                return -271828
            else:
                return 314159
        else: #isnan(f):
            return 0
    v, expo = math.frexp(f)
    v *= TAKE_NEXT
    hipart = int(v)
    v = (v - float(hipart)) * TAKE_NEXT
    x = hipart + int(v) + (expo << 15)
    return intmask(x)
Пример #31
0
def float_is_integer__Float(space, w_float):
    v = w_float.floatval
    if not rfloat.isfinite(v):
        return space.w_False
    return space.wrap(math.floor(v) == v)
Пример #32
0
 def fn(x, y):
     n1 = x * x
     n2 = y * y * y
     return rfloat.isfinite(n1 / n2)
Пример #33
0
 def fn(x, y):
     n1 = x * x
     n2 = y * y * y
     return rfloat.isfinite(n1 / n2)
Пример #34
0
def float_pack(x, size):
    """Convert a Python float x into a 64-bit unsigned integer
    with the same byte representation."""

    if size == 8:
        MIN_EXP = -1021  # = sys.float_info.min_exp
        MAX_EXP = 1024  # = sys.float_info.max_exp
        MANT_DIG = 53  # = sys.float_info.mant_dig
        BITS = 64
    elif size == 4:
        MIN_EXP = -125  # C's FLT_MIN_EXP
        MAX_EXP = 128  # FLT_MAX_EXP
        MANT_DIG = 24  # FLT_MANT_DIG
        BITS = 32
    else:
        raise ValueError("invalid size value")

    sign = rfloat.copysign(1.0, x) < 0.0
    if not rfloat.isfinite(x):
        if rfloat.isinf(x):
            mant = r_ulonglong(0)
            exp = MAX_EXP - MIN_EXP + 2
        else:  # rfloat.isnan(x):
            mant = r_ulonglong(1) << (MANT_DIG - 2)  # other values possible
            exp = MAX_EXP - MIN_EXP + 2
    elif x == 0.0:
        mant = r_ulonglong(0)
        exp = 0
    else:
        m, e = math.frexp(abs(x))  # abs(x) == m * 2**e
        exp = e - (MIN_EXP - 1)
        if exp > 0:
            # Normal case.
            mant = round_to_nearest(m * (r_ulonglong(1) << MANT_DIG))
            mant -= 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 not objectmodel.we_are_translated():
            assert 0 <= mant <= 1 << MANT_DIG - 1
        if mant == r_ulonglong(1) << MANT_DIG - 1:
            mant = r_ulonglong(0)
            exp += 1

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

    # check constraints
    if not objectmodel.we_are_translated():
        assert 0 <= mant < 1 << MANT_DIG - 1
        assert 0 <= exp <= MAX_EXP - MIN_EXP + 2
        assert 0 <= sign <= 1

    exp = r_ulonglong(exp)
    sign = r_ulonglong(sign)
    return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant
Пример #35
0
def float_pack(x, size):
    """Convert a Python float x into a 64-bit unsigned integer
    with the same byte representation."""

    if size == 8:
        MIN_EXP = -1021  # = sys.float_info.min_exp
        MAX_EXP = 1024   # = sys.float_info.max_exp
        MANT_DIG = 53    # = sys.float_info.mant_dig
        BITS = 64
    elif size == 4:
        MIN_EXP = -125   # C's FLT_MIN_EXP
        MAX_EXP = 128    # FLT_MAX_EXP
        MANT_DIG = 24    # FLT_MANT_DIG
        BITS = 32
    else:
        raise ValueError("invalid size value")

    sign = rfloat.copysign(1.0, x) < 0.0
    if not rfloat.isfinite(x):
        if rfloat.isinf(x):
            mant = r_ulonglong(0)
            exp = MAX_EXP - MIN_EXP + 2
        else:  # rfloat.isnan(x):
            mant = r_ulonglong(1) << (MANT_DIG-2) # other values possible
            exp = MAX_EXP - MIN_EXP + 2
    elif x == 0.0:
        mant = r_ulonglong(0)
        exp = 0
    else:
        m, e = math.frexp(abs(x))  # abs(x) == m * 2**e
        exp = e - (MIN_EXP - 1)
        if exp > 0:
            # Normal case.
            mant = round_to_nearest(m * (r_ulonglong(1) << MANT_DIG))
            mant -= 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 not objectmodel.we_are_translated():
            assert 0 <= mant <= 1 << MANT_DIG - 1
        if mant == r_ulonglong(1) << MANT_DIG - 1:
            mant = r_ulonglong(0)
            exp += 1

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

    # check constraints
    if not objectmodel.we_are_translated():
        assert 0 <= mant < 1 << MANT_DIG - 1
        assert 0 <= exp <= MAX_EXP - MIN_EXP + 2
        assert 0 <= sign <= 1

    exp = r_ulonglong(exp)
    sign = r_ulonglong(sign)
    return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant
Пример #36
0
def float_is_integer__Float(space, w_float):
    v = w_float.floatval
    if not rfloat.isfinite(v):
        return space.w_False
    return space.wrap(math.floor(v) == v)