[pypy-svn] r75707 - in pypy/branch/fast-forward/pypy: objspace/std objspace/std/test rlib
benjamin at codespeak.net
benjamin at codespeak.net
Thu Jul 1 00:14:49 CEST 2010
Author: benjamin
Date: Thu Jul 1 00:14:47 2010
New Revision: 75707
Modified:
pypy/branch/fast-forward/pypy/objspace/std/floatobject.py
pypy/branch/fast-forward/pypy/objspace/std/newformat.py
pypy/branch/fast-forward/pypy/objspace/std/test/test_newformat.py
pypy/branch/fast-forward/pypy/rlib/rarithmetic.py
Log:
cobble some code together for float formatting
Modified: pypy/branch/fast-forward/pypy/objspace/std/floatobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/floatobject.py (original)
+++ pypy/branch/fast-forward/pypy/objspace/std/floatobject.py Thu Jul 1 00:14:47 2010
@@ -1,7 +1,7 @@
import operator, new
from pypy.interpreter import gateway
from pypy.interpreter.error import OperationError
-from pypy.objspace.std import model
+from pypy.objspace.std import model, newformat
from pypy.objspace.std.multimethod import FailedToImplementArgs
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
@@ -106,6 +106,9 @@
def str__Float(space, w_float):
return float2string(space, w_float, "%.12g")
+def format__Float_ANY(space, w_float, w_spec):
+ return newformat.get_formatter(space, w_spec).format_float(w_float)
+
# ____________________________________________________________
# A mess to handle all cases of float comparison without relying
# on delegation, which can unfortunately loose precision when
Modified: pypy/branch/fast-forward/pypy/objspace/std/newformat.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/newformat.py (original)
+++ pypy/branch/fast-forward/pypy/objspace/std/newformat.py Thu Jul 1 00:14:47 2010
@@ -419,15 +419,15 @@
self._calc_padding(string, length)
return space.wrap(self._pad(string))
- def _get_locale(self, locale_kind):
+ def _get_locale(self, tp):
space = self.space
- if locale_kind == CURRENT_LOCALE:
+ if tp == "n":
dec, thousands, grouping = rlocale.numeric_formatting()
- elif locale_kind == DEFAULT_LOCALE:
+ elif self._thousands_sep:
dec = "."
thousands = ","
grouping = "\3\0"
- elif locale_kind == NO_LOCALE:
+ else:
dec = "."
thousands = ""
grouping = "\256"
@@ -445,7 +445,7 @@
spec.n_digits = n_number - n_remainder - has_dec
spec.n_prefix = n_prefix
spec.n_lpadding = 0
- spec.n_decimal = 1 if has_dec else 0
+ spec.n_decimal = int(has_dec)
spec.n_remainder = n_remainder
spec.n_spadding = 0
spec.n_rpadding = 0
@@ -548,7 +548,7 @@
def _fill_number(self, spec, num, to_digits, n_digits, to_prefix, fill_char,
- upper):
+ to_remainder, upper):
out = self._builder()
if spec.n_lpadding:
out.append_multiple_char(fill_char, spec.n_lpadding)
@@ -563,16 +563,16 @@
out.append_multiple_char(fill_char, spec.n_spadding)
if spec.n_digits != 0:
if self._loc_thousands:
- num = self._grouped_digits
+ digits = self._grouped_digits
else:
- num = num[to_digits:]
+ digits = num[to_digits:to_digits + spec.n_digits]
if upper:
- num = self._upcase_string(num)
- out.append(num)
+ digits = self._upcase_string(digits)
+ out.append(digits)
if spec.n_decimal:
out.append(".")
if spec.n_remainder:
- out.append(num[0])
+ out.append(num[to_remainder:])
if spec.n_rpadding:
out.append_multiple_char(fill_char, spec.n_rpadding)
return self.space.wrap(out.build())
@@ -598,6 +598,7 @@
result = chr(value)
n_digits = 1
n_remainder = 1
+ to_remainder = 0
n_prefix = 0
to_prefix = 0
to_numeric = 0
@@ -628,20 +629,15 @@
to_prefix += 1
n_digits = len(result) - skip_leading
n_remainder = 0
+ to_remainder = 0
to_numeric = skip_leading
- if tp == "n":
- locale_kind = CURRENT_LOCALE
- elif self._thousands_sep:
- locale_kind = DEFAULT_LOCALE
- else:
- locale_kind = NO_LOCALE
- self._get_locale(locale_kind)
+ self._get_locale(tp)
spec = self._calc_num_width(n_prefix, sign_char, to_numeric, n_digits,
n_remainder, False, result)
fill = " " if self._fill_char == "\0" else self._fill_char
upper = self._type == "X"
return self._fill_number(spec, result, to_numeric, n_digits, to_prefix,
- fill, upper)
+ fill, to_remainder, upper)
def _long_to_base(self, base, value):
prefix = ""
@@ -718,24 +714,63 @@
tp == "G" or
tp == "%"):
w_float = space.float(w_num)
- self._format_float(w_float)
+ return self._format_float(w_float)
else:
self._unknown_presentation("int" if kind == INT_KIND else "long")
+ def _parse_number(self, s, i):
+ length = len(s)
+ while i < length and "0" <= s[i] <= "9":
+ i += 1
+ rest = i
+ dec_point = i < length and s[i] == "."
+ if dec_point:
+ rest += 1
+ return dec_point, rest
+
def _format_float(self, w_float):
space = self.space
+ flags = 0
+ default_precision = 6
if self._alternate:
msg = "alternate form not allowed in float formats"
raise OperationError(space.w_ValueError, space.wrap(msg))
tp = self._type
if tp == "\0":
tp = "g"
+ default_prec = 12
+ flags |= rarithmetic.DTSF_ADD_DOT_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 = 6
+ self._precision = default_precision
+ result, special = rarithmetic.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
+ self._get_locale(tp)
+ spec = self._calc_num_width(0, sign, to_number, n_digits,
+ n_remainder, have_dec_point, result)
+ fill = " " if self._fill_char == "\0" else self._fill_char
+ return self._fill_number(spec, result, to_number, None, 0, fill,
+ to_remainder, False)
def format_float(self, w_float):
space = self.space
Modified: pypy/branch/fast-forward/pypy/objspace/std/test/test_newformat.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/test/test_newformat.py (original)
+++ pypy/branch/fast-forward/pypy/objspace/std/test/test_newformat.py Thu Jul 1 00:14:47 2010
@@ -215,3 +215,15 @@
def setup_class(cls):
cls.w_i = cls.space.w_long
+
+
+class AppTestFloatFormatting:
+
+ def test_alternate(self):
+ raises(ValueError, format, 1.0, "#")
+
+ def test_simple(self):
+ assert format(0.0, "f") == "0.000000"
+
+ def test_sign(self):
+ assert format(-1.23, "1") == "-1.23"
Modified: pypy/branch/fast-forward/pypy/rlib/rarithmetic.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/rarithmetic.py (original)
+++ pypy/branch/fast-forward/pypy/rlib/rarithmetic.py Thu Jul 1 00:14:47 2010
@@ -465,6 +465,22 @@
return formatd(fmt, x)
+DTSF_ADD_DOT_0 = 1
+
+DIST_FINITE = 1
+DIST_NAN = 2
+DIST_INFINITY = 3
+
+def double_to_string(value, tp, precision, flags):
+ if isnan(value):
+ special = DIST_NAN
+ elif isinf(value):
+ special = DIST_INFINITY
+ else:
+ special = DIST_FINITE
+ result = formatd_overflow(False, precision, tp, value)
+ return result, special
+
# the 'float' C type
class r_singlefloat(object):
More information about the Pypy-commit
mailing list