Exemplo n.º 1
0
        def _format_float(self, w_float):
            """helper for format_float"""
            space = self.space
            flags = 0
            default_precision = 6
            if self._alternate:
                flags |= rfloat.DTSF_ALT

            tp = self._type
            self._get_locale(tp)
            if tp == "\0":
                flags |= rfloat.DTSF_ADD_DOT_0
                tp = "r"
                default_precision = 0
            elif tp == "n":
                tp = "g"
            value = space.float_w(w_float)
            if tp == "%":
                tp = "f"
                value *= 100
                add_pct = True
            else:
                add_pct = False
            if self._precision == -1:
                self._precision = default_precision
            elif tp == "r":
                tp = "g"
            result, special = rfloat.double_to_string(value, tp,
                                                      self._precision, flags)
            if add_pct:
                result += "%"
            n_digits = len(result)
            if result[0] == "-":
                sign = "-"
                to_number = 1
                n_digits -= 1
            else:
                sign = "\0"
                to_number = 0
            have_dec_point, to_remainder = self._parse_number(
                result, to_number)
            n_remainder = len(result) - to_remainder
            if self.is_unicode:
                digits = result.decode("latin-1")
            else:
                digits = result
            spec = self._calc_num_width(0, sign, to_number, n_digits,
                                        n_remainder, have_dec_point, digits)
            fill = self._fill_char
            return self.space.wrap(
                self._fill_number(spec, digits, to_number, 0, fill,
                                  to_remainder, False))
Exemplo n.º 2
0
        def _format_float(self, w_float):
            """helper for format_float"""
            space = self.space
            flags = 0
            default_precision = 6
            if self._alternate:
               flags |= rfloat.DTSF_ALT

            tp = self._type
            self._get_locale(tp)
            if tp == "\0":
                flags |= rfloat.DTSF_ADD_DOT_0
                tp = "r"
                default_precision = 0
            elif tp == "n":
                tp = "g"
            value = space.float_w(w_float)
            if tp == "%":
                tp = "f"
                value *= 100
                add_pct = True
            else:
                add_pct = False
            if self._precision == -1:
                self._precision = default_precision
            elif tp == "r":
                tp = "g"
            result, special = rfloat.double_to_string(value, tp,
                                                      self._precision, flags)
            if add_pct:
                result += "%"
            n_digits = len(result)
            if result[0] == "-":
                sign = "-"
                to_number = 1
                n_digits -= 1
            else:
                sign = "\0"
                to_number = 0
            have_dec_point, to_remainder = self._parse_number(result, to_number)
            n_remainder = len(result) - to_remainder
            if self.is_unicode:
                digits = result.decode("latin-1")
            else:
                digits = result
            spec = self._calc_num_width(0, sign, to_number, n_digits,
                                        n_remainder, have_dec_point, digits)
            fill = self._fill_char
            return self.space.wrap(self._fill_number(spec, digits, to_number, 0,
                                      fill, to_remainder, False))
Exemplo n.º 3
0
def PyOS_double_to_string(space, val, format_code, precision, flags, ptype):
    """Convert a double val to a string using supplied
    format_code, precision, and flags.

    format_code must be one of 'e', 'E', 'f', 'F',
    'g', 'G' or 'r'.  For 'r', the supplied precision
    must be 0 and is ignored.  The 'r' format code specifies the
    standard repr() format.

    flags can be zero or more of the values Py_DTSF_SIGN,
    Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together:

    Py_DTSF_SIGN means to always precede the returned string with a sign
    character, even if val is non-negative.

    Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look
    like an integer.

    Py_DTSF_ALT means to apply "alternate" formatting rules.  See the
    documentation for the PyOS_snprintf() '#' specifier for
    details.

    If ptype is non-NULL, then the value it points to will be set to one of
    Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that
    val is a finite number, an infinite number, or not a number, respectively.

    The return value is a pointer to buffer with the converted string or
    NULL if the conversion failed. The caller is responsible for freeing the
    returned string by calling PyMem_Free().
    """
    buffer, rtype = rfloat.double_to_string(val, format_code,
                                            intmask(precision),
                                            intmask(flags))
    if ptype != lltype.nullptr(rffi.INTP.TO):
        ptype[0] = rffi.cast(rffi.INT, DOUBLE_TO_STRING_TYPES_MAP[rtype])
    bufp = rffi.str2charp(buffer)
    return bufp
Exemplo n.º 4
0
def PyOS_double_to_string(space, val, format_code, precision, flags, ptype):
    """Convert a double val to a string using supplied
    format_code, precision, and flags.

    format_code must be one of 'e', 'E', 'f', 'F',
    'g', 'G' or 'r'.  For 'r', the supplied precision
    must be 0 and is ignored.  The 'r' format code specifies the
    standard repr() format.

    flags can be zero or more of the values Py_DTSF_SIGN,
    Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together:

    Py_DTSF_SIGN means to always precede the returned string with a sign
    character, even if val is non-negative.

    Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look
    like an integer.

    Py_DTSF_ALT means to apply "alternate" formatting rules.  See the
    documentation for the PyOS_snprintf() '#' specifier for
    details.

    If ptype is non-NULL, then the value it points to will be set to one of
    Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that
    val is a finite number, an infinite number, or not a number, respectively.

    The return value is a pointer to buffer with the converted string or
    NULL if the conversion failed. The caller is responsible for freeing the
    returned string by calling PyMem_Free().
    """
    buffer, rtype = rfloat.double_to_string(val, format_code,
                                            intmask(precision),
                                            intmask(flags))
    if ptype != lltype.nullptr(INTP_real.TO):
        ptype[0] = rffi.cast(rffi.INT_real, DOUBLE_TO_STRING_TYPES_MAP[rtype])
    bufp = rffi.str2charp(buffer)
    return bufp
Exemplo n.º 5
0
 def _repr(self, prec=14):
     _str, _ = double_to_string(self.floatval, "G", prec, DTSF_CUT_EXP_0)
     if 'E' in _str and '.' not in _str:
         a, b = _str.split('E')
         return a + '.0E' + b
     return _str
Exemplo n.º 6
0
        def _format_complex(self, w_complex):
            flags = 0
            space = self.space
            tp = self._type
            self._get_locale(tp)
            default_precision = 6
            if self._align == "=":
                # '=' alignment is invalid
                raise oefmt(space.w_ValueError,
                            "'=' alignment flag is not allowed in complex "
                            "format specifier")
            if self._fill_char == "0":
                # zero padding is invalid
                raise oefmt(space.w_ValueError,
                            "Zero padding is not allowed in complex format "
                            "specifier")
            if self._alternate:
                flags |= rfloat.DTSF_ALT

            skip_re = 0
            add_parens = 0
            if tp == "\0":
                #should mirror str() output
                tp = "g"
                default_precision = 12
                #test if real part is non-zero
                if (w_complex.realval == 0 and
                    math.copysign(1., w_complex.realval) == 1.):
                    skip_re = 1
                else:
                    add_parens = 1

            if tp == "n":
                #same as 'g' except for locale, taken care of later
                tp = "g"

            #check if precision not set
            if self._precision == -1:
                self._precision = default_precision

            #in CPython it's named 're' - clashes with re module
            re_num, special = rfloat.double_to_string(w_complex.realval, tp, self._precision, flags)
            im_num, special = rfloat.double_to_string(w_complex.imagval, tp, self._precision, flags)
            n_re_digits = len(re_num)
            n_im_digits = len(im_num)

            to_real_number = 0
            to_imag_number = 0
            re_sign = im_sign = ''
            #if a sign character is in the output, remember it and skip
            if re_num[0] == "-":
                re_sign = "-"
                to_real_number = 1
                n_re_digits -= 1
            if im_num[0] == "-":
                im_sign = "-"
                to_imag_number = 1
                n_im_digits -= 1

            #turn off padding - do it after number composition
            #calc_num_width uses self._width, so assign to temporary variable,
            #calculate width of real and imag parts, then reassign padding, align
            tmp_fill_char = self._fill_char
            tmp_align = self._align
            tmp_width = self._width
            self._fill_char = "\0"
            self._align = "<"
            self._width = -1

            #determine if we have remainder, might include dec or exponent or both
            re_have_dec, re_remainder_ptr = self._parse_number(re_num,
                                                               to_real_number)
            im_have_dec, im_remainder_ptr = self._parse_number(im_num,
                                                               to_imag_number)

            if self.is_unicode:
                re_num = rutf8.decode_latin_1(re_num)
                im_num = rutf8.decode_latin_1(im_num)

            #set remainder, in CPython _parse_number sets this
            #using n_re_digits causes tests to fail
            re_n_remainder = len(re_num) - re_remainder_ptr
            im_n_remainder = len(im_num) - im_remainder_ptr
            re_spec = self._calc_num_width(0, re_sign, to_real_number, n_re_digits,
                                           re_n_remainder, re_have_dec,
                                           re_num)

            #capture grouped digits b/c _fill_number reads from self._grouped_digits
            #self._grouped_digits will get overwritten in imaginary calc_num_width
            re_grouped_digits = self._grouped_digits
            if not skip_re:
                self._sign = "+"
            im_spec = self._calc_num_width(0, im_sign, to_imag_number, n_im_digits,
                                           im_n_remainder, im_have_dec,
                                           im_num)

            im_grouped_digits = self._grouped_digits
            if skip_re:
                re_spec.n_total = 0

            #reassign width, alignment, fill character
            self._align = tmp_align
            self._width = tmp_width
            self._fill_char = tmp_fill_char

            #compute L and R padding - stored in self._left_pad and self._right_pad
            self._calc_padding("", re_spec.n_total + im_spec.n_total + 1 +
                                           add_parens * 2)

            out = self._builder()
            fill = self._fill_char

            #compose the string
            #add left padding
            out.append_multiple_char(fill, self._left_pad)
            if add_parens:
                out.append(self._lit('(')[0])

            #if the no. has a real component, add it
            if not skip_re:
                out.append(self._fill_number(re_spec, re_num, to_real_number, 0,
                                             fill, re_remainder_ptr, False,
                                             re_grouped_digits))

            #add imaginary component
            out.append(self._fill_number(im_spec, im_num, to_imag_number, 0,
                                         fill, im_remainder_ptr, False,
                                         im_grouped_digits))

            #add 'j' character
            out.append(self._lit('j')[0])

            if add_parens:
                out.append(self._lit(')')[0])

            #add right padding
            out.append_multiple_char(fill, self._right_pad)

            return self.wrap(out.build())
Exemplo n.º 7
0
 def _repr(self, prec=14):
     _str, _ = double_to_string(self.floatval, "G", prec, DTSF_CUT_EXP_0)
     if 'E' in _str and '.' not in _str:
         a, b = _str.split('E')
         return a + '.0E' + b
     return _str
Exemplo n.º 8
0
 def get_as_string(self):
     string, _ = double_to_string(self.value, 'G', 12, flags=0)
     return string
Exemplo n.º 9
0
        def _format_complex(self, w_complex):
            flags = 0
            space = self.space
            tp = self._type
            self._get_locale(tp)
            default_precision = 6
            if self._align == "=":
                # '=' alignment is invalid
                msg = ("'=' alignment flag is not allowed in"
                       " complex format specifier")
                raise OperationError(space.w_ValueError, space.wrap(msg))
            if self._fill_char == "0":
                #zero padding is invalid
                msg = "Zero padding is not allowed in complex format specifier"
                raise OperationError(space.w_ValueError, space.wrap(msg))
            if self._alternate:
                flags |= rfloat.DTSF_ALT

            skip_re = 0
            add_parens = 0
            if tp == "\0":
                #should mirror str() output
                tp = "g"
                default_precision = 12
                #test if real part is non-zero
                if (w_complex.realval == 0 and
                    copysign(1., w_complex.realval) == 1.):
                    skip_re = 1
                else:
                    add_parens = 1

            if tp == "n":
                #same as 'g' except for locale, taken care of later
                tp = "g"

            #check if precision not set
            if self._precision == -1:
                self._precision = default_precision

            #in CPython it's named 're' - clashes with re module
            re_num, special = rfloat.double_to_string(w_complex.realval, tp, self._precision, flags)
            im_num, special = rfloat.double_to_string(w_complex.imagval, tp, self._precision, flags)
            n_re_digits = len(re_num)
            n_im_digits = len(im_num)

            to_real_number = 0
            to_imag_number = 0
            re_sign = im_sign = ''
            #if a sign character is in the output, remember it and skip
            if re_num[0] == "-":
                re_sign = "-"
                to_real_number = 1
                n_re_digits -= 1
            if im_num[0] == "-":
                im_sign = "-"
                to_imag_number = 1
                n_im_digits -= 1

            #turn off padding - do it after number composition
            #calc_num_width uses self._width, so assign to temporary variable,
            #calculate width of real and imag parts, then reassign padding, align
            tmp_fill_char = self._fill_char
            tmp_align = self._align
            tmp_width = self._width
            self._fill_char = "\0"
            self._align = "<"
            self._width = -1

            #determine if we have remainder, might include dec or exponent or both
            re_have_dec, re_remainder_ptr = self._parse_number(re_num,
                                                               to_real_number)
            im_have_dec, im_remainder_ptr = self._parse_number(im_num,
                                                               to_imag_number)

            if self.is_unicode:
                re_num = re_num.decode("latin-1")
                im_num = im_num.decode("latin-1")

            #set remainder, in CPython _parse_number sets this
            #using n_re_digits causes tests to fail
            re_n_remainder = len(re_num) - re_remainder_ptr
            im_n_remainder = len(im_num) - im_remainder_ptr
            re_spec = self._calc_num_width(0, re_sign, to_real_number, n_re_digits,
                                           re_n_remainder, re_have_dec,
                                           re_num)

            #capture grouped digits b/c _fill_number reads from self._grouped_digits
            #self._grouped_digits will get overwritten in imaginary calc_num_width
            re_grouped_digits = self._grouped_digits
            if not skip_re:
                self._sign = "+"
            im_spec = self._calc_num_width(0, im_sign, to_imag_number, n_im_digits,
                                           im_n_remainder, im_have_dec,
                                           im_num)

            im_grouped_digits = self._grouped_digits
            if skip_re:
                re_spec.n_total = 0

            #reassign width, alignment, fill character
            self._align = tmp_align
            self._width = tmp_width
            self._fill_char = tmp_fill_char

            #compute L and R padding - stored in self._left_pad and self._right_pad
            self._calc_padding(self.empty, re_spec.n_total + im_spec.n_total + 1 +
                                           add_parens * 2)

            out = self._builder()
            fill = self._fill_char

            #compose the string
            #add left padding
            out.append_multiple_char(fill, self._left_pad)
            if add_parens:
                out.append(self._lit('(')[0])

            #if the no. has a real component, add it
            if not skip_re:
                out.append(self._fill_number(re_spec, re_num, to_real_number, 0,
                                             fill, re_remainder_ptr, False,
                                             re_grouped_digits))

            #add imaginary component
            out.append(self._fill_number(im_spec, im_num, to_imag_number, 0,
                                         fill, im_remainder_ptr, False,
                                         im_grouped_digits))

            #add 'j' character
            out.append(self._lit('j')[0])

            if add_parens:
                out.append(self._lit(')')[0])

            #add right padding
            out.append_multiple_char(fill, self._right_pad)

            return self.space.wrap(out.build())