[pypy-svn] r79964 - in pypy/branch/fast-forward/pypy: objspace/std rlib rlib/test rpython/lltypesystem rpython/module rpython/module/test translator/c/src translator/c/test
afa at codespeak.net
afa at codespeak.net
Sat Dec 11 00:34:43 CET 2010
Author: afa
Date: Sat Dec 11 00:34:40 2010
New Revision: 79964
Modified:
pypy/branch/fast-forward/pypy/objspace/std/complexobject.py
pypy/branch/fast-forward/pypy/objspace/std/floatobject.py
pypy/branch/fast-forward/pypy/rlib/rarithmetic.py
pypy/branch/fast-forward/pypy/rlib/rmarshal.py
pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py
pypy/branch/fast-forward/pypy/rlib/test/test_rmarshal.py
pypy/branch/fast-forward/pypy/rpython/lltypesystem/ll_str.py
pypy/branch/fast-forward/pypy/rpython/module/ll_strtod.py
pypy/branch/fast-forward/pypy/rpython/module/test/test_ll_strtod.py
pypy/branch/fast-forward/pypy/translator/c/src/ll_strtod.h
pypy/branch/fast-forward/pypy/translator/c/test/test_extfunc.py
pypy/branch/fast-forward/pypy/translator/c/test/test_standalone.py
Log:
Refactor formatd() to not take a printf-like format,
but several arguments instead.
This prepares for the inclusion of the dtoa functions.
Modified: pypy/branch/fast-forward/pypy/objspace/std/complexobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/complexobject.py (original)
+++ pypy/branch/fast-forward/pypy/objspace/std/complexobject.py Sat Dec 11 00:34:40 2010
@@ -3,7 +3,8 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.floatobject import W_FloatObject, _hash_float
-from pypy.rlib.rarithmetic import formatd, isinf, isnan, copysign
+from pypy.rlib.rarithmetic import (
+ formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
import math
@@ -255,7 +256,7 @@
#w_imag = space.call_function(space.w_float,space.wrap(-w_self.imagval))
return space.newcomplex(w_self.realval,-w_self.imagval)
-def format_float(x, format):
+def format_float(x, code, precision):
# like float2string, except that the ".0" is not necessary
if isinf(x):
if x > 0.0:
@@ -265,12 +266,12 @@
elif isnan(x):
return "nan"
else:
- return formatd(format, x)
+ return formatd(x, code, precision)
def repr_format(x):
- return format_float(x, "%.17g")
+ return format_float(x, 'r', 0)
def str_format(x):
- return format_float(x, "%.12g")
+ return format_float(x, 'g', DTSF_STR_PRECISION)
def repr__Complex(space, w_complex):
if w_complex.realval == 0 and copysign(1., w_complex.realval) == 1.:
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 Sat Dec 11 00:34:40 2010
@@ -9,7 +9,8 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.longobject import W_LongObject
from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf, isnan
-from pypy.rlib.rarithmetic import formatd, LONG_BIT, INFINITY, copysign
+from pypy.rlib.rarithmetic import (LONG_BIT, INFINITY, copysign,
+ formatd, DTSF_ADD_DOT_0, DTSF_STR_PRECISION)
from pypy.rlib.rbigint import rbigint
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib import rfloat
@@ -130,7 +131,7 @@
else:
return space.wrap("0x%sp%s%d" % (s, sign, exp))
-def float2string(space, w_float, format):
+def float2string(space, w_float, code, precision):
x = w_float.floatval
# we special-case explicitly inf and nan here
if isinf(x):
@@ -141,23 +142,14 @@
elif isnan(x):
s = "nan"
else:
- s = formatd(format, x)
- # We want float numbers to be recognizable as such,
- # i.e., they should contain a decimal point or an exponent.
- # However, %g may print the number as an integer;
- # in such cases, we append ".0" to the string.
- for c in s:
- if c in '.eE':
- break
- else:
- s += '.0'
+ s = formatd(x, code, precision, DTSF_ADD_DOT_0)
return space.wrap(s)
def repr__Float(space, w_float):
- return float2string(space, w_float, "%.17g")
+ return float2string(space, w_float, 'r', 0)
def str__Float(space, w_float):
- return float2string(space, w_float, "%.12g")
+ return float2string(space, w_float, 'g', DTSF_STR_PRECISION)
def format__Float_ANY(space, w_float, w_spec):
return newformat.run_formatter(space, w_spec, "format_float", w_float)
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 Sat Dec 11 00:34:40 2010
@@ -555,35 +555,60 @@
# float -> string
-formatd_max_length = 120
+DTSF_STR_PRECISION = 12
-def formatd(fmt, x):
- return fmt % (x,)
+DTSF_SIGN = 0x1
+DTSF_ADD_DOT_0 = 0x2
+DTSF_ALT = 0x4
-def formatd_overflow(alt, prec, kind, x):
- # msvcrt does not support the %F format.
- # OTOH %F and %f only differ for 'inf' or 'nan' numbers
- # which are already handled elsewhere
- if kind == 'F':
- kind = 'f'
+DIST_FINITE = 1
+DIST_NAN = 2
+DIST_INFINITY = 3
- if ((kind in 'gG' and formatd_max_length <= 10+prec) or
- (kind in 'fF' and formatd_max_length <= 53+prec)):
- raise OverflowError("formatted float is too long (precision too large?)")
- if alt:
+formatd_ADD_DOT_0 = 0x1
+
+def formatd(x, code, precision, flags=0):
+ "NOT_RPYTHON"
+ if flags & DTSF_ALT:
alt = '#'
else:
alt = ''
- fmt = "%%%s.%d%s" % (alt, prec, kind)
+ if code == 'r':
+ fmt = "%r"
+ else:
+ fmt = "%%%s.%d%s" % (alt, precision, code)
+ s = fmt % (x,)
- return formatd(fmt, x)
+ if flags & formatd_ADD_DOT_0:
+ # We want float numbers to be recognizable as such,
+ # i.e., they should contain a decimal point or an exponent.
+ # However, %g may print the number as an integer;
+ # in such cases, we append ".0" to the string.
+ for c in s:
+ if c in '.eE':
+ break
+ else:
+ s += '.0'
+ elif code == 'r' and s.endswith('.0'):
+ s = s[:-2]
-DTSF_ADD_DOT_0 = 1
+ return s
-DIST_FINITE = 1
-DIST_NAN = 2
-DIST_INFINITY = 3
+formatd_max_length = 120
+
+def formatd_overflow(x, kind, precision, flags=0):
+ # msvcrt does not support the %F format.
+ # OTOH %F and %f only differ for 'inf' or 'nan' numbers
+ # which are already handled elsewhere
+ if kind == 'F':
+ kind = 'f'
+
+ if ((kind in 'gG' and formatd_max_length < 10+precision) or
+ (kind in 'fF' and formatd_max_length < 53+precision)):
+ raise OverflowError("formatted float is too long (precision too large?)")
+
+ return formatd(x, kind, precision, flags)
def double_to_string(value, tp, precision, flags):
if isnan(value):
@@ -592,7 +617,7 @@
special = DIST_INFINITY
else:
special = DIST_FINITE
- result = formatd_overflow(False, precision, tp, value)
+ result = formatd_overflow(value, tp, precision)
return result, special
# the 'float' C type
Modified: pypy/branch/fast-forward/pypy/rlib/rmarshal.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/rmarshal.py (original)
+++ pypy/branch/fast-forward/pypy/rlib/rmarshal.py Sat Dec 11 00:34:40 2010
@@ -195,7 +195,7 @@
def dump_float(buf, x):
buf.append(TYPE_FLOAT)
- s = formatd("%.17g", x)
+ s = formatd(x, 'g', 17)
buf.append(chr(len(s)))
buf += s
add_dumper(annmodel.SomeFloat(), dump_float)
Modified: pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py (original)
+++ pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py Sat Dec 11 00:34:40 2010
@@ -338,10 +338,18 @@
def test_formatd(self):
from pypy.rlib.rarithmetic import formatd
def f(x):
- return formatd('%.2f', x)
+ return formatd(x, 'f', 2, 0)
res = self.ll_to_string(self.interpret(f, [10/3.0]))
assert res == '3.33'
+ def test_formatd_repr(self):
+ py.test.skip('WIP: Need full dtoa support to run this test')
+ from pypy.rlib.rarithmetic import formatd
+ def f(x):
+ return formatd(x, 'r', 0, 0)
+ res = self.ll_to_string(self.interpret(f, [1.1]))
+ assert res == '1.1'
+
def test_formatd_overflow(self):
from pypy.translator.c.test.test_genc import compile
from pypy.rlib.rarithmetic import formatd_overflow
@@ -349,7 +357,7 @@
def func(x):
# Test the %F format, which is not supported by
# the Microsoft's msvcrt library.
- return formatd_overflow(0, 4, 'F', x)
+ return formatd_overflow(x, 'F', 4)
f = compile(func, [float])
assert f(10/3.0) == '3.3333'
Modified: pypy/branch/fast-forward/pypy/rlib/test/test_rmarshal.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/test/test_rmarshal.py (original)
+++ pypy/branch/fast-forward/pypy/rlib/test/test_rmarshal.py Sat Dec 11 00:34:40 2010
@@ -147,7 +147,7 @@
def f():
result = ''
for num, string, fval in unmarshaller(buf):
- result += '%d=%s/%s;' % (num, string, formatd('%.17g', fval))
+ result += '%d=%s/%s;' % (num, string, formatd(fval, 'g', 17))
return result
res = interpret(f, [])
res = ''.join(res.chars)
Modified: pypy/branch/fast-forward/pypy/rpython/lltypesystem/ll_str.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/lltypesystem/ll_str.py (original)
+++ pypy/branch/fast-forward/pypy/rpython/lltypesystem/ll_str.py Sat Dec 11 00:34:40 2010
@@ -126,5 +126,5 @@
ll_int2oct._pure_function_ = True
def ll_float_str(repr, f):
- return llstr(formatd("%f", f))
+ return llstr(formatd(f, 'f', 6))
ll_float_str._pure_function_ = True
Modified: pypy/branch/fast-forward/pypy/rpython/module/ll_strtod.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/module/ll_strtod.py (original)
+++ pypy/branch/fast-forward/pypy/rpython/module/ll_strtod.py Sat Dec 11 00:34:40 2010
@@ -24,17 +24,20 @@
@registering(rarithmetic.formatd)
def register_formatd(self):
ll_strtod = self.llexternal('LL_strtod_formatd',
- [rffi.CCHARP, rffi.DOUBLE], rffi.CCHARP,
+ [rffi.DOUBLE, rffi.CHAR, rffi.INT], rffi.CCHARP,
sandboxsafe=True, threadsafe=False)
- def llimpl(fmt, x):
- res = ll_strtod(fmt, x)
+ def llimpl(x, code, precision, flags):
+ if code == 'r':
+ code = 'g'
+ precision = 17
+ res = ll_strtod(x, code, precision)
return rffi.charp2str(res)
- def oofakeimpl(fmt, x):
- return ootype.oostring(rarithmetic.formatd(fmt._str, x), -1)
+ def oofakeimpl(x, code, precision, flags):
+ return ootype.oostring(rarithmetic.formatd(x, code, precision, flags), -1)
- return extdef([str, float], str, 'll_strtod.ll_strtod_formatd',
+ return extdef([float, lltype.Char, int, int], str, 'll_strtod.ll_strtod_formatd',
llimpl=llimpl, oofakeimpl=oofakeimpl,
sandboxsafe=True)
Modified: pypy/branch/fast-forward/pypy/rpython/module/test/test_ll_strtod.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/module/test/test_ll_strtod.py (original)
+++ pypy/branch/fast-forward/pypy/rpython/module/test/test_ll_strtod.py Sat Dec 11 00:34:40 2010
@@ -6,7 +6,7 @@
class BaseTestStrtod(BaseRtypingTest):
def test_formatd(self):
def f(y):
- return rarithmetic.formatd("%.2f", y)
+ return rarithmetic.formatd(y, 'f', 2)
assert self.ll_to_string(self.interpret(f, [3.0])) == f(3.0)
Modified: pypy/branch/fast-forward/pypy/translator/c/src/ll_strtod.h
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/src/ll_strtod.h (original)
+++ pypy/branch/fast-forward/pypy/translator/c/src/ll_strtod.h Sat Dec 11 00:34:40 2010
@@ -13,7 +13,7 @@
double LL_strtod_parts_to_float(char *sign, char *beforept,
char *afterpt, char *exponent);
-char *LL_strtod_formatd(char *fmt, double x);
+char *LL_strtod_formatd(double x, char code, int precision);
/* implementations */
@@ -86,9 +86,16 @@
#define snprintf _snprintf
#endif
-char* LL_strtod_formatd(char *fmt, double x) {
+char* LL_strtod_formatd(double x, char code, int precision) {
int res;
- res = snprintf(buffer, buflen, fmt, x);
+ const char* fmt;
+ if (code == 'f') fmt = "%.*f";
+ else if (code == 'g') fmt = "%.*g";
+ else {
+ strcpy(buffer, "??.?"); /* should not occur */
+ return buffer;
+ }
+ res = snprintf(buffer, buflen, fmt, precision, x);
if (res <= 0 || res >= buflen) {
strcpy(buffer, "??.?"); /* should not occur */
} else {
Modified: pypy/branch/fast-forward/pypy/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/test/test_extfunc.py (original)
+++ pypy/branch/fast-forward/pypy/translator/c/test/test_extfunc.py Sat Dec 11 00:34:40 2010
@@ -283,7 +283,7 @@
def test_rarith_formatd():
from pypy.rlib.rarithmetic import formatd
def fn(x):
- return formatd("%.2f", x)
+ return formatd(x, 'f', 2, 0)
f = compile(fn, [float])
Modified: pypy/branch/fast-forward/pypy/translator/c/test/test_standalone.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/test/test_standalone.py (original)
+++ pypy/branch/fast-forward/pypy/translator/c/test/test_standalone.py Sat Dec 11 00:34:40 2010
@@ -239,7 +239,7 @@
fname2 = dirname.join("test_genc.c")
fname2.write("""
void f() {
- LL_strtod_formatd("%5f", 12.3);
+ LL_strtod_formatd(12.3, 'f', 5);
}""")
files = [fname, fname2]
More information about the Pypy-commit
mailing list