Example #1
0
def string_to_float(s):
    """
    Conversion of string to float.
    This version tries to only raise on invalid literals.
    Overflows should be converted to infinity whenever possible.

    Expects an unwrapped string and return an unwrapped float.
    """
    from rpython.rlib.rstring import strip_spaces, ParseStringError

    s = strip_spaces(s)
    if not s:
        raise ParseStringError(INVALID_MSG)

    low = s.lower()
    if low == "-inf" or low == "-infinity":
        return -INFINITY
    elif low == "inf" or low == "+inf":
        return INFINITY
    elif low == "infinity" or low == "+infinity":
        return INFINITY
    elif low == "nan" or low == "+nan":
        return NAN
    elif low == "-nan":
        return -NAN

    try:
        return rstring_to_float(s)
    except ValueError:
        raise ParseStringError(INVALID_MSG)
Example #2
0
def _str2num(s, radix):
    from rpython.rlib import rarithmetic, rfloat, rbigint
    from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError
    from rpython.rlib.rsre import rsre_re as re
    import math
    try:
        if ((radix == 16 and re.match("^[0-9A-Fa-f]+$", s))
                or (radix == 8 and re.match("^[0-7]+$", s))
                or (radix == 10 and re.match("^[0-9]+$", s))):
            try:
                return values.W_Fixnum(rarithmetic.string_to_int(s,
                                                                 base=radix))
            except ParseStringOverflowError:
                return values.W_Bignum(rbigint.rbigint.fromstr(s, base=radix))
        if re.match("[+-]?([\d]+)?.?\d+[tT]\d", s):
            # it's an extflonum
            return values.W_ExtFlonum(s)

        if re.match("[+-]?([\d]+)?.?\d+[sf]\d", s):
            if "f" in s:
                f_parts = s.split("f")
            elif "s" in s:
                f_parts = s.split("s")
            else:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            if len(f_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            try:
                numb = float(f_parts[0])
                prec = int(f_parts[1])
                p = math.pow(10, prec)
            except ValueError, e:
                return values.w_false

            return values.W_Flonum.make(numb * p, True)

        if re.match("[+-]?([\d]+)?.?\d+e\d", s):
            e_parts = s.split("e")
            if len(e_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            try:
                num = float(e_parts[0])
                exp = int(e_parts[1])
                p = math.pow(10, exp)
            except ValueError, e:
                return values.w_false

            return values.W_Flonum(num * p)
Example #3
0
def str2num(w_s, radix, convert_mode, decimal_mode):
    from rpython.rlib import rarithmetic, rfloat, rbigint
    from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError
    from rpython.rlib.rsre import rsre_re as re
    import math

    s = w_s.as_str_utf8()
    try:
        if re.match("[+-]?([\d]+)?.?\d+[tT]\d", s):
            # it's an extflonum
            return values.W_ExtFlonum(s)

        if re.match("[+-]?([\d]+)?.?\d+[sf]\d", s):
            if "f" in s:
                f_parts = s.split("f")
            elif "s" in s:
                f_parts = s.split("s")
            else:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            if len(f_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            try:
                numb = float(f_parts[0])
                prec = int(f_parts[1])
                p = math.pow(10, prec)
            except ValueError:
                return values.w_false

            return values.W_Flonum.make(numb * p, True)

        if re.match("[+-]?([\d]+)?.?\d+e\d", s):
            e_parts = s.split("e")
            if len(e_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            try:
                num = float(e_parts[0])
                exp = int(e_parts[1])
                p = math.pow(10, exp)
            except ValueError:
                return values.w_false

            return values.W_Flonum(num * p)

        if "." in s or re.match("[+-]?([\d]+)(\.[\d]+)?e[+-][\d]+$", s):
            if not radix.equal(values.W_Fixnum(10)):  # FIXME
                raise SchemeException(
                    "string->number : floats with base different than 10 are not supported yet : given number : %s - radix : %s"
                    % (w_s.tostring(), radix.tostring()))
            return values.W_Flonum(rfloat.string_to_float(s))
        else:
            try:
                return values.W_Fixnum(
                    rarithmetic.string_to_int(s, base=radix.toint()))
            except ParseStringOverflowError:
                return values.W_Bignum(rbigint.rbigint.fromstr(s))
    except ParseStringError as e:
        return values.w_false