Amaury Forgeot d'Arc avatar Amaury Forgeot d'Arc committed d7a6c72

Move float/double related code from rarithmetic.py to rfloat.py

Comments (0)

Files changed (46)

pypy/annotation/model.py

 from pypy.tool.pairtype import pair, extendabletype
 from pypy.tool.tls import tlsobject
 from pypy.rlib.rarithmetic import r_uint, r_ulonglong, base_int
-from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat, isnan
+from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat
 import inspect, weakref
 
 DEBUG = False    # set to False to disable recording of debugging information
     def __eq__(self, other):
         if (type(self) is SomeFloat and type(other) is SomeFloat and
             self.is_constant() and other.is_constant()):
+            from pypy.rlib.rfloat import isnan, copysign
             # NaN unpleasantness.
             if isnan(self.const) and isnan(other.const):
                 return True
             # 0.0 vs -0.0 unpleasantness.
             if not self.const and not other.const:
-                from pypy.rlib.rarithmetic import copysign
                 return copysign(1., self.const) == copysign(1., other.const)
             #
         return super(SomeFloat, self).__eq__(other)

pypy/interpreter/astcompiler/assemble.py

 
 from pypy.interpreter.error import OperationError
 from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 
 
 class Instruction(object):
         w_type = space.type(obj)
         if space.is_w(w_type, space.w_float):
             val = space.float_w(obj)
-            if val == 0.0 and rarithmetic.copysign(1., val) < 0:
+            if val == 0.0 and rfloat.copysign(1., val) < 0:
                 w_key = space.newtuple([obj, space.w_float, space.w_None])
             else:
                 w_key = space.newtuple([obj, space.w_float])
             real = space.float_w(w_real)
             imag = space.float_w(w_imag)
             real_negzero = (real == 0.0 and
-                            rarithmetic.copysign(1., real) < 0)
+                            rfloat.copysign(1., real) < 0)
             imag_negzero = (imag == 0.0 and
-                            rarithmetic.copysign(1., imag) < 0)
+                            rfloat.copysign(1., imag) < 0)
             if real_negzero and imag_negzero:
                 tup = [obj, space.w_complex, space.w_None, space.w_None,
                        space.w_None]

pypy/jit/backend/test/runner_test.py

         if not self.cpu.supports_floats:
             py.test.skip("requires floats")
 
-        from pypy.rlib.rarithmetic import INFINITY, NAN, isinf, isnan
+        from pypy.rlib.rfloat import INFINITY, NAN, isinf, isnan
         from pypy.jit.metainterp.resoperation import opname
 
         fzer = boxfloat(0.0)

pypy/jit/backend/x86/test/test_zmath.py

 from pypy.module.math.test import test_direct
 from pypy.translator.c.test.test_genc import compile
 from pypy.jit.backend.x86.support import ensure_sse2_floats
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 
 
 def get_test_case((fnname, args, expected)):
     try:
         fn = getattr(math, fnname)
     except AttributeError:
-        fn = getattr(rarithmetic, fnname)
+        fn = getattr(rfloat, fnname)
     expect_valueerror = (expected == ValueError)
     expect_overflowerror = (expected == OverflowError)
     check = test_direct.get_tester(expected)

pypy/module/__builtin__/operation.py

 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef
 from pypy.rlib.runicode import UNICHR
-from pypy.rlib.rarithmetic import isnan, isinf, round_double
+from pypy.rlib.rfloat import isnan, isinf, round_double
 from pypy.rlib import rfloat
 import math
 import __builtin__

pypy/module/cmath/constant.py

 import math
-from pypy.rlib.rarithmetic import isinf
+from pypy.rlib.rfloat import isinf
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 

pypy/module/cmath/interp_cmath.py

 import math
 from math import fabs
 from pypy.rlib.objectmodel import specialize
-from pypy.rlib.rarithmetic import copysign, asinh, log1p, isinf, isnan
+from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import NoneNotWrapped

pypy/module/cmath/special_value.py

 import math
-from pypy.rlib.rarithmetic import isnan, isinf, copysign
+from pypy.rlib.rfloat import isnan, isinf, copysign
 
 # code to deal with special values (infinities, NaNs, ...)
 #

pypy/module/cmath/test/test_cmath.py

 from __future__ import with_statement
 from pypy.conftest import gettestobjspace
-from pypy.rlib.rarithmetic import copysign, isnan, isinf
+from pypy.rlib.rfloat import copysign, isnan, isinf
 from pypy.module.cmath import interp_cmath
 import os, sys, math
 

pypy/module/math/interp_math.py

 import math
 import sys
 
-from pypy.rlib import rarithmetic, unroll
+from pypy.rlib import rfloat, unroll
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import NoneNotWrapped
 
     # No exceptions possible.
     x = _get_double(space, w_x)
     y = _get_double(space, w_y)
-    return space.wrap(rarithmetic.copysign(x, y))
+    return space.wrap(rfloat.copysign(x, y))
 
 def isinf(space, w_x):
     """Return True if x is infinity."""
-    return space.wrap(rarithmetic.isinf(_get_double(space, w_x)))
+    return space.wrap(rfloat.isinf(_get_double(space, w_x)))
 
 def isnan(space, w_x):
     """Return True if x is not a number."""
-    return space.wrap(rarithmetic.isnan(_get_double(space, w_x)))
+    return space.wrap(rfloat.isnan(_get_double(space, w_x)))
 
 def pow(space, w_x, w_y):
     """pow(x,y)
             v = hi
         del partials[added:]
         if v != 0.0:
-            if rarithmetic.isinf(v) or rarithmetic.isnan(v):
-                if (not rarithmetic.isinf(original) and
-                    not rarithmetic.isnan(original)):
+            if rfloat.isinf(v) or rfloat.isnan(v):
+                if (not rfloat.isinf(original) and
+                    not rfloat.isnan(original)):
                     raise OperationError(space.w_OverflowError,
                                          space.wrap("intermediate overflow"))
-                if rarithmetic.isinf(original):
+                if rfloat.isinf(original):
                     inf_sum += original
                 special_sum += original
                 del partials[:]
             else:
                 partials.append(v)
     if special_sum != 0.0:
-        if rarithmetic.isnan(special_sum):
+        if rfloat.isnan(special_sum):
             raise OperationError(space.w_ValueError, space.wrap("-inf + inf"))
         return space.wrap(special_sum)
     hi = 0.0
 
 def log1p(space, w_x):
     """Find log(x + 1)."""
-    return math1(space, rarithmetic.log1p, w_x)
+    return math1(space, rfloat.log1p, w_x)
 
 def acosh(space, w_x):
     """Inverse hyperbolic cosine"""
-    return math1(space, rarithmetic.acosh, w_x)
+    return math1(space, rfloat.acosh, w_x)
 
 def asinh(space, w_x):
     """Inverse hyperbolic sine"""
-    return math1(space, rarithmetic.asinh, w_x)
+    return math1(space, rfloat.asinh, w_x)
 
 def atanh(space, w_x):
     """Inverse hyperbolic tangent"""
-    return math1(space, rarithmetic.atanh, w_x)
+    return math1(space, rfloat.atanh, w_x)
 
 def expm1(space, w_x):
     """exp(x) - 1"""
-    return math1(space, rarithmetic.expm1, w_x)
+    return math1(space, rfloat.expm1, w_x)
 
 def erf(space, w_x):
     """The error function"""
     return p / q * x * math.exp(-x2) / _sqrtpi
 
 def _erf(x):
-    if rarithmetic.isnan(x):
+    if rfloat.isnan(x):
         return x
     absx = abs(x)
     if absx < ERF_SERIES_CUTOFF:
         return 1. - cf if x > 0. else cf - 1.
 
 def _erfc(x):
-    if rarithmetic.isnan(x):
+    if rfloat.isnan(x):
         return x
     absx = abs(x)
     if absx < ERF_SERIES_CUTOFF:
 
 def _sinpi(x):
     y = math.fmod(abs(x), 2.)
-    n = int(rarithmetic.round_away(2. * y))
+    n = int(rfloat.round_away(2. * y))
     if n == 0:
         r = math.sin(math.pi * y)
     elif n == 1:
         r = math.sin(math.pi * (y - 2.))
     else:
         raise AssertionError("should not reach")
-    return rarithmetic.copysign(1., x) * r
+    return rfloat.copysign(1., x) * r
 
 _lanczos_g = 6.024680040776729583740234375
 _lanczos_g_minus_half = 5.524680040776729583740234375
     return num / den
 
 def _gamma(x):
-    if rarithmetic.isnan(x) or (rarithmetic.isinf(x) and x > 0.):
+    if rfloat.isnan(x) or (rfloat.isinf(x) and x > 0.):
         return x
-    if rarithmetic.isinf(x):
+    if rfloat.isinf(x):
         raise ValueError("math domain error")
     if x == 0.:
         raise ValueError("math domain error")
     absx = abs(x)
     if absx < 1e-20:
         r = 1. / x
-        if rarithmetic.isinf(r):
+        if rfloat.isinf(r):
             raise OverflowError("math range error")
         return r
     if absx > 200.:
             sqrtpow = math.pow(y, absx / 2. - .25)
             r *= sqrtpow
             r *= sqrtpow
-    if rarithmetic.isinf(r):
+    if rfloat.isinf(r):
         raise OverflowError("math range error")
     return r
 
 def _lgamma(x):
-    if rarithmetic.isnan(x):
+    if rfloat.isnan(x):
         return x
-    if rarithmetic.isinf(x):
-        return rarithmetic.INFINITY
+    if rfloat.isinf(x):
+        return rfloat.INFINITY
     if x == math.floor(x) and x <= 2.:
         if x <= 0.:
             raise ValueError("math range error")
         r = (math.log(math.pi) - math.log(abs(_sinpi(absx))) - math.log(absx) -
              (math.log(_lanczos_sum(absx)) - _lanczos_g +
               (absx - .5) * (math.log(absx + _lanczos_g - .5) - 1)))
-    if rarithmetic.isinf(r):
+    if rfloat.isinf(r):
         raise OverflowError("math domain error")
     return r

pypy/module/math/test/test_direct.py

 """
 
 import py, sys, math
-from pypy.rlib import rarithmetic
-from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN
+from pypy.rlib import rfloat
+from pypy.rlib.rfloat import isinf, isnan, INFINITY, NAN
 
 consistent_host = True
 if '__pypy__' not in sys.builtin_module_names:
         try:
             fn = getattr(math, fnname)
         except AttributeError:
-            fn = getattr(rarithmetic, fnname)
+            fn = getattr(rfloat, fnname)
         do_test(fn, fnname, args, expected)
     #
     dict[fnname] = dict.get(fnname, 0) + 1

pypy/module/sys/system.py

 """Information about the current system."""
 from pypy.interpreter import gateway
 from pypy.rlib import rfloat, rbigint
-from pypy.rlib.rarithmetic import USE_SHORT_FLOAT_REPR
 from pypy.rpython.lltypesystem import rffi
 
 
     return space.call_function(w_long_info, space.newtuple(info_w))
 
 def get_float_repr_style(space):
-    if USE_SHORT_FLOAT_REPR:
+    if rfloat.USE_SHORT_FLOAT_REPR:
         return space.wrap("short")
     else:
-        return space.wrap("legacy")
+        return space.wrap("legacy")

pypy/objspace/std/complexobject.py

 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.floatobject import W_FloatObject, _hash_float
 from pypy.objspace.std.longobject import W_LongObject
-from pypy.rlib.rarithmetic import (
+from pypy.rlib.rfloat import (
     formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
 
 import math

pypy/objspace/std/floatobject.py

 from pypy.objspace.std.register_all import register_all
 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 (LONG_BIT, INFINITY, copysign,
-    formatd, DTSF_ADD_DOT_0, DTSF_STR_PRECISION, NAN)
+from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT
+from pypy.rlib.rfloat import (
+    isinf, isnan, INFINITY, NAN, 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

pypy/objspace/std/floattype.py

         i += 1
         if length - i >= 2 and s[i:i + 2].lower() == "nf":
             i += 2
-            value = rarithmetic.INFINITY
+            value = rfloat.INFINITY
             if length - i >= 5 and s[i:i + 5].lower() == "inity":
                 i += 5
     elif s[i] == "n" or s[i] == "N":
         i += 1
         if length - i >= 2 and s[i:i + 2].lower() == "an":
             i += 2
-            value = rarithmetic.NAN
+            value = rfloat.NAN
     else:
         if (s[i] == "0" and length - i > 1 and
             (s[i + 1] == "x" or s[i + 1] == "X")):

pypy/objspace/std/formatting.py

 String formatting routines.
 """
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.rarithmetic import (
-    ovfcheck, formatd, DTSF_ALT, isnan, isinf)
+from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rlib.rfloat import formatd, DTSF_ALT, isnan, isinf
 from pypy.interpreter.error import OperationError
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib.rstring import StringBuilder, UnicodeBuilder

pypy/objspace/std/newformat.py

 import string
 
 from pypy.interpreter.error import OperationError
-from pypy.rlib import rstring, runicode, rlocale, rarithmetic
+from pypy.rlib import rstring, runicode, rlocale, rarithmetic, rfloat
 from pypy.rlib.objectmodel import specialize
-from pypy.rlib.rarithmetic import copysign, formatd
+from pypy.rlib.rfloat import copysign, formatd
 
 
 @specialize.argtype(1)
         if tp == "\0":
             tp = "g"
             default_precision = 12
-            flags |= rarithmetic.DTSF_ADD_DOT_0
+            flags |= rfloat.DTSF_ADD_DOT_0
         elif tp == "n":
             tp = "g"
         value = space.float_w(w_float)
             add_pct = False
         if self._precision == -1:
             self._precision = default_precision
-        result, special = rarithmetic.double_to_string(value, tp,
-                                                       self._precision, flags)
+        result, special = rfloat.double_to_string(value, tp,
+                                                  self._precision, flags)
         if add_pct:
             result += "%"
         n_digits = len(result)

pypy/objspace/std/strutil.py

 Pure Python implementation of string utilities.
 """
 
-from pypy.rlib.rarithmetic import ovfcheck, rstring_to_float, INFINITY, NAN
+from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rlib.rfloat import rstring_to_float, INFINITY, NAN
 from pypy.rlib.rbigint import rbigint, parse_digit_string
 from pypy.interpreter.error import OperationError
 import math

pypy/rlib/objectmodel.py

     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, isinf, isnan
+    from pypy.rlib.rarithmetic import intmask
+    from pypy.rlib.rfloat import isinf, isnan
     if isinf(f):
         if f < 0.0:
             return -271828

pypy/rlib/rarithmetic.py

 
 
 """
-import sys, math
+import sys
 from pypy.rpython import extregistry
 from pypy.rlib import objectmodel
 
-USE_SHORT_FLOAT_REPR = True # XXX make it a translation option?
-
 # set up of machine internals
 _bits = 0
 _itest = 1
     LONG_BIT_SHIFT += 1
     assert LONG_BIT_SHIFT < 99, "LONG_BIT_SHIFT value not found?"
 
-INFINITY = 1e200 * 1e200
-NAN = INFINITY / INFINITY
-
-try:
-    # Try to get math functions added in 2.6.
-    from math import isinf, isnan, copysign, acosh, asinh, atanh, log1p
-except ImportError:
-    def isinf(x):
-        "NOT_RPYTHON"
-        return x == INFINITY or x == -INFINITY
-
-    def isnan(v):
-        "NOT_RPYTHON"
-        return v != v
-
-    def copysign(x, y):
-        """NOT_RPYTHON. Return x with the sign of y"""
-        if x < 0.:
-            x = -x
-        if y > 0. or (y == 0. and math.atan2(y, -1.) > 0.):
-            return x
-        else:
-            return -x
-
-    _2_to_m28 = 3.7252902984619141E-09; # 2**-28
-    _2_to_p28 = 268435456.0; # 2**28
-    _ln2 = 6.93147180559945286227E-01
-
-    def acosh(x):
-        "NOT_RPYTHON"
-        if isnan(x):
-            return NAN
-        if x < 1.:
-            raise ValueError("math domain error")
-        if x >= _2_to_p28:
-            if isinf(x):
-                return x
-            else:
-                return math.log(x) + _ln2
-        if x == 1.:
-            return 0.
-        if x >= 2.:
-            t = x * x
-            return math.log(2. * x - 1. / (x + math.sqrt(t - 1.0)))
-        t = x - 1.0
-        return log1p(t + math.sqrt(2. * t + t * t))
-
-    def asinh(x):
-        "NOT_RPYTHON"
-        absx = abs(x)
-        if isnan(x) or isinf(x):
-            return x
-        if absx < _2_to_m28:
-            return x
-        if absx > _2_to_p28:
-            w = math.log(absx) + _ln2
-        elif absx > 2.:
-            w = math.log(2. * absx + 1. / (math.sqrt(x * x + 1.) + absx))
-        else:
-            t = x * x
-            w = log1p(absx + t / (1. + math.sqrt(1. + t)))
-        return copysign(w, x)
-
-    def atanh(x):
-        "NOT_RPYTHON"
-        if isnan(x):
-            return x
-        absx = abs(x)
-        if absx >= 1.:
-            raise ValueError("math domain error")
-        if absx < _2_to_m28:
-            return x
-        if absx < .5:
-            t = absx + absx
-            t = .5 * log1p(t + t * absx / (1. - absx))
-        else:
-            t = .5 * log1p((absx + absx) / (1. - absx))
-        return copysign(t, x)
-
-    def log1p(x):
-        "NOT_RPYTHON"
-        from pypy.rlib import rfloat
-        if abs(x) < rfloat.DBL_EPSILON // 2.:
-            return x
-        elif -.5 <= x <= 1.:
-            y = 1. + x
-            return math.log(y) - ((y - 1.) - x) / y
-        else:
-            return math.log(1. + x)
-
-try:
-    from math import expm1 # Added in Python 2.7.
-except ImportError:
-    def expm1(x):
-        "NOT_RPYTHON"
-        if abs(x) < .7:
-            u = math.exp(x)
-            if u == 1.:
-                return x
-            return (u - 1.) * x / math.log(u)
-        return math.exp(x) - 1.
-
-def round_away(x):
-    # round() from libm, which is not available on all platforms!
-    absx = abs(x)
-    if absx - math.floor(absx) >= .5:
-        r = math.ceil(absx)
-    else:
-        r = math.floor(absx)
-    return copysign(r, x)
-
 def intmask(n):
     if isinstance(n, int):
         return int(n)   # possibly bool->int
 # successfully be casted to an int.
 if sys.maxint == 2147483647:
     def ovfcheck_float_to_int(x):
+        from pypy.rlib.rfloat import isnan
         if isnan(x):
             raise OverflowError
         if -2147483649.0 < x < 2147483648.0:
     # Note the "<= x <" here, as opposed to "< x <" above.
     # This is justified by test_typed in translator/c/test.
     def ovfcheck_float_to_int(x):
+        from pypy.rlib.rfloat import isnan
         if isnan(x):
             raise OverflowError
         if -9223372036854776832.0 <= x < 9223372036854775296.0:
     r_int64 = int
 
 
-def rstring_to_float(s):
-    if USE_SHORT_FLOAT_REPR:
-        from pypy.rlib.rdtoa import strtod
-        return strtod(s)
-
-    sign, before_point, after_point, exponent = break_up_float(s)
-
-    if not before_point and not after_point:
-        raise ValueError
-
-    return parts_to_float(sign, before_point, after_point, exponent)
-
-# float as string  -> sign, beforept, afterpt, exponent
-def break_up_float(s):
-    i = 0
-
-    sign = ''
-    before_point = ''
-    after_point = ''
-    exponent = ''
-
-    if s[i] in '+-':
-        sign = s[i]
-        i += 1
-
-    while i < len(s) and s[i] in '0123456789':
-        before_point += s[i]
-        i += 1
-
-    if i == len(s):
-        return sign, before_point, after_point, exponent
-
-    if s[i] == '.':
-        i += 1
-        while i < len(s) and s[i] in '0123456789':
-            after_point += s[i]
-            i += 1
-            
-        if i == len(s):
-            return sign, before_point, after_point, exponent
-
-    if s[i] not in  'eE':
-        raise ValueError
-
-    i += 1
-    if i == len(s):
-        raise ValueError
-
-    if s[i] in '-+':
-        exponent += s[i]
-        i += 1
-
-    if i == len(s):
-        raise ValueError
-    
-    while i < len(s) and s[i] in '0123456789':
-        exponent += s[i]
-        i += 1
-
-    if i != len(s):
-        raise ValueError
-
-    return sign, before_point, after_point, exponent
-
-# string -> float helper
-
-def parts_to_float(sign, beforept, afterpt, exponent):
-    "NOT_RPYTHON"
-    if not exponent:
-        exponent = '0'
-    return float("%s%s.%se%s" % (sign, beforept, afterpt, exponent))
-
-# float -> string
-
-DTSF_STR_PRECISION = 12
-
-DTSF_SIGN      = 0x1
-DTSF_ADD_DOT_0 = 0x2
-DTSF_ALT       = 0x4
-
-DIST_FINITE   = 1
-DIST_NAN      = 2
-DIST_INFINITY = 3
-
-# Equivalent to CPython's PyOS_double_to_string
-def _formatd(x, code, precision, flags):
-    "NOT_RPYTHON"
-    if flags & DTSF_ALT:
-        alt = '#'
-    else:
-        alt = ''
-
-    if code == 'r':
-        fmt = "%r"
-    else:
-        fmt = "%%%s.%d%s" % (alt, precision, code)
-    s = fmt % (x,)
-
-    if flags & DTSF_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]
-
-    return s
-
-def formatd(x, code, precision, flags=0):
-    if USE_SHORT_FLOAT_REPR:
-        from pypy.rlib.rdtoa import dtoa_formatd
-        return dtoa_formatd(x, code, precision, flags)
-    else:
-        return _formatd(x, code, precision, flags)
-
-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(value, tp, precision, flags)
-    return result, special
-
-if USE_SHORT_FLOAT_REPR:
-    def round_double(value, ndigits):
-        # The basic idea is very simple: convert and round the double to
-        # a decimal string using _Py_dg_dtoa, then convert that decimal
-        # string back to a double with _Py_dg_strtod.  There's one minor
-        # difficulty: Python 2.x expects round to do
-        # round-half-away-from-zero, while _Py_dg_dtoa does
-        # round-half-to-even.  So we need some way to detect and correct
-        # the halfway cases.
-
-        # a halfway value has the form k * 0.5 * 10**-ndigits for some
-        # odd integer k.  Or in other words, a rational number x is
-        # exactly halfway between two multiples of 10**-ndigits if its
-        # 2-valuation is exactly -ndigits-1 and its 5-valuation is at
-        # least -ndigits.  For ndigits >= 0 the latter condition is
-        # automatically satisfied for a binary float x, since any such
-        # float has nonnegative 5-valuation.  For 0 > ndigits >= -22, x
-        # needs to be an integral multiple of 5**-ndigits; we can check
-        # this using fmod.  For -22 > ndigits, there are no halfway
-        # cases: 5**23 takes 54 bits to represent exactly, so any odd
-        # multiple of 0.5 * 10**n for n >= 23 takes at least 54 bits of
-        # precision to represent exactly.
-
-        sign = copysign(1.0, value)
-        value = abs(value)
-
-        # find 2-valuation value
-        m, expo = math.frexp(value)
-        while m != math.floor(m):
-            m *= 2.0
-            expo -= 1
-
-        # determine whether this is a halfway case.
-        halfway_case = 0
-        if expo == -ndigits - 1:
-            if ndigits >= 0:
-                halfway_case = 1
-            elif ndigits >= -22:
-                # 22 is the largest k such that 5**k is exactly
-                # representable as a double
-                five_pow = 1.0
-                for i in range(-ndigits):
-                    five_pow *= 5.0
-                if math.fmod(value, five_pow) == 0.0:
-                    halfway_case = 1
-
-        # round to a decimal string; use an extra place for halfway case
-        strvalue = formatd(value, 'f', ndigits + halfway_case)
-
-        if halfway_case:
-            buf = [c for c in strvalue]
-            if ndigits >= 0:
-                endpos = len(buf) - 1
-            else:
-                endpos = len(buf) + ndigits
-            # Sanity checks: there should be exactly ndigits+1 places
-            # following the decimal point, and the last digit in the
-            # buffer should be a '5'
-            if not objectmodel.we_are_translated():
-                assert buf[endpos] == '5'
-                if '.' in buf:
-                    assert endpos == len(buf) - 1
-                    assert buf.index('.') == len(buf) - ndigits - 2
-
-            # increment and shift right at the same time
-            i = endpos - 1
-            carry = 1
-            while i >= 0:
-                digit = ord(buf[i])
-                if digit == ord('.'):
-                    buf[i+1] = chr(digit)
-                    i -= 1
-                    digit = ord(buf[i])
-
-                carry += digit - ord('0')
-                buf[i+1] = chr(carry % 10 + ord('0'))
-                carry /= 10
-                i -= 1
-            buf[0] = chr(carry + ord('0'))
-            if ndigits < 0:
-                buf.append('0')
-
-            strvalue = ''.join(buf)
-
-        return sign * rstring_to_float(strvalue)
-
-else:
-    # fallback version, to be used when correctly rounded
-    # binary<->decimal conversions aren't available
-    def round_double(value, ndigits):
-        if ndigits >= 0:
-            if ndigits > 22:
-                # pow1 and pow2 are each safe from overflow, but
-                # pow1*pow2 ~= pow(10.0, ndigits) might overflow
-                pow1 = math.pow(10.0, ndigits - 22)
-                pow2 = 1e22
-            else:
-                pow1 = math.pow(10.0, ndigits)
-                pow2 = 1.0
-
-            y = (value * pow1) * pow2
-            # if y overflows, then rounded value is exactly x
-            if isinf(y):
-                return value
-
-        else:
-            pow1 = math.pow(10.0, -ndigits);
-            pow2 = 1.0 # unused; for translation
-            y = value / pow1
-
-        if y >= 0.0:
-            z = math.floor(y + 0.5)
-        else:
-            z = math.ceil(y - 0.5)
-        if math.fabs(y-z) == 1.0:   # obscure case, see the test
-            z = y
-
-        if ndigits >= 0:
-            z = (z / pow2) / pow1
-        else:
-            z *= pow1
-        return z
-
 # the 'float' C type
 
 class r_singlefloat(object):

pypy/rlib/rbigint.py

 from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong
-from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, isinf, isnan
+from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen
 from pypy.rlib.rarithmetic import most_neg_value_of_same_type
+from pypy.rlib.rfloat import isinf, isnan
 from pypy.rlib.debug import make_sure_not_resized, check_regular_int
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rpython.lltypesystem import lltype, rffi

pypy/rlib/rdtoa.py

 from __future__ import with_statement
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.tool.autopath import pypydir
 from pypy.rpython.lltypesystem import lltype, rffi
     if digits[0] == 'i' or digits[0] == 'I':
         if sign == 1:
             return special_strings[2]
-        elif flags & rarithmetic.DTSF_SIGN:
+        elif flags & rfloat.DTSF_SIGN:
             return special_strings[1]
         else:
             return special_strings[0]
             use_exp = True
         elif decpt > precision:
             use_exp = True
-        elif flags & rarithmetic.DTSF_ADD_DOT_0 and decpt == precision:
+        elif flags & rfloat.DTSF_ADD_DOT_0 and decpt == precision:
             use_exp = True
-        if flags & rarithmetic.DTSF_ALT:
+        if flags & rfloat.DTSF_ALT:
             vdigits_end = precision
     elif code == 'r':
         #  convert to exponential format at 1e16.  We used to convert
     else:
         vdigits_start = 0
     if vdigits_end <= decpt:
-        if not use_exp and flags & rarithmetic.DTSF_ADD_DOT_0:
+        if not use_exp and flags & rfloat.DTSF_ADD_DOT_0:
             vdigits_end = decpt + 1
         else:
             vdigits_end = decpt
 
     if sign == 1:
         builder.append('-')
-    elif flags & rarithmetic.DTSF_SIGN:
+    elif flags & rfloat.DTSF_SIGN:
         builder.append('+')
 
     # note that exactly one of the three 'if' conditions is true, so
     s = builder.build()
 
     # Delete a trailing decimal pt unless using alternative formatting.
-    if not flags & rarithmetic.DTSF_ALT:
+    if not flags & rfloat.DTSF_ALT:
         last = len(s) - 1
         if last >= 0 and s[last] == '.':
             s = s[:last]

pypy/rlib/rfloat.py

 """Float constants"""
 
+import math
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rlib import objectmodel
 
+USE_SHORT_FLOAT_REPR = True # XXX make it a translation option?
 
 class CConfig:
     _compilation_info_ = ExternalCompilationInfo(includes=["float.h"])
 del float_constants, int_constants, const
 
 globals().update(rffi_platform.configure(CConfig))
+
+def rstring_to_float(s):
+    if USE_SHORT_FLOAT_REPR:
+        from pypy.rlib.rdtoa import strtod
+        return strtod(s)
+
+    sign, before_point, after_point, exponent = break_up_float(s)
+
+    if not before_point and not after_point:
+        raise ValueError
+
+    return parts_to_float(sign, before_point, after_point, exponent)
+
+# float as string  -> sign, beforept, afterpt, exponent
+def break_up_float(s):
+    i = 0
+
+    sign = ''
+    before_point = ''
+    after_point = ''
+    exponent = ''
+
+    if s[i] in '+-':
+        sign = s[i]
+        i += 1
+
+    while i < len(s) and s[i] in '0123456789':
+        before_point += s[i]
+        i += 1
+
+    if i == len(s):
+        return sign, before_point, after_point, exponent
+
+    if s[i] == '.':
+        i += 1
+        while i < len(s) and s[i] in '0123456789':
+            after_point += s[i]
+            i += 1
+            
+        if i == len(s):
+            return sign, before_point, after_point, exponent
+
+    if s[i] not in  'eE':
+        raise ValueError
+
+    i += 1
+    if i == len(s):
+        raise ValueError
+
+    if s[i] in '-+':
+        exponent += s[i]
+        i += 1
+
+    if i == len(s):
+        raise ValueError
+    
+    while i < len(s) and s[i] in '0123456789':
+        exponent += s[i]
+        i += 1
+
+    if i != len(s):
+        raise ValueError
+
+    return sign, before_point, after_point, exponent
+
+# string -> float helper
+
+def parts_to_float(sign, beforept, afterpt, exponent):
+    "NOT_RPYTHON"
+    if not exponent:
+        exponent = '0'
+    return float("%s%s.%se%s" % (sign, beforept, afterpt, exponent))
+
+# float -> string
+
+DTSF_STR_PRECISION = 12
+
+DTSF_SIGN      = 0x1
+DTSF_ADD_DOT_0 = 0x2
+DTSF_ALT       = 0x4
+
+DIST_FINITE   = 1
+DIST_NAN      = 2
+DIST_INFINITY = 3
+
+# Equivalent to CPython's PyOS_double_to_string
+def _formatd(x, code, precision, flags):
+    "NOT_RPYTHON"
+    if flags & DTSF_ALT:
+        alt = '#'
+    else:
+        alt = ''
+
+    if code == 'r':
+        fmt = "%r"
+    else:
+        fmt = "%%%s.%d%s" % (alt, precision, code)
+    s = fmt % (x,)
+
+    if flags & DTSF_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]
+
+    return s
+
+def formatd(x, code, precision, flags=0):
+    if USE_SHORT_FLOAT_REPR:
+        from pypy.rlib.rdtoa import dtoa_formatd
+        return dtoa_formatd(x, code, precision, flags)
+    else:
+        return _formatd(x, code, precision, flags)
+
+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(value, tp, precision, flags)
+    return result, special
+
+if USE_SHORT_FLOAT_REPR:
+    def round_double(value, ndigits):
+        # The basic idea is very simple: convert and round the double to
+        # a decimal string using _Py_dg_dtoa, then convert that decimal
+        # string back to a double with _Py_dg_strtod.  There's one minor
+        # difficulty: Python 2.x expects round to do
+        # round-half-away-from-zero, while _Py_dg_dtoa does
+        # round-half-to-even.  So we need some way to detect and correct
+        # the halfway cases.
+
+        # a halfway value has the form k * 0.5 * 10**-ndigits for some
+        # odd integer k.  Or in other words, a rational number x is
+        # exactly halfway between two multiples of 10**-ndigits if its
+        # 2-valuation is exactly -ndigits-1 and its 5-valuation is at
+        # least -ndigits.  For ndigits >= 0 the latter condition is
+        # automatically satisfied for a binary float x, since any such
+        # float has nonnegative 5-valuation.  For 0 > ndigits >= -22, x
+        # needs to be an integral multiple of 5**-ndigits; we can check
+        # this using fmod.  For -22 > ndigits, there are no halfway
+        # cases: 5**23 takes 54 bits to represent exactly, so any odd
+        # multiple of 0.5 * 10**n for n >= 23 takes at least 54 bits of
+        # precision to represent exactly.
+
+        sign = copysign(1.0, value)
+        value = abs(value)
+
+        # find 2-valuation value
+        m, expo = math.frexp(value)
+        while m != math.floor(m):
+            m *= 2.0
+            expo -= 1
+
+        # determine whether this is a halfway case.
+        halfway_case = 0
+        if expo == -ndigits - 1:
+            if ndigits >= 0:
+                halfway_case = 1
+            elif ndigits >= -22:
+                # 22 is the largest k such that 5**k is exactly
+                # representable as a double
+                five_pow = 1.0
+                for i in range(-ndigits):
+                    five_pow *= 5.0
+                if math.fmod(value, five_pow) == 0.0:
+                    halfway_case = 1
+
+        # round to a decimal string; use an extra place for halfway case
+        strvalue = formatd(value, 'f', ndigits + halfway_case)
+
+        if halfway_case:
+            buf = [c for c in strvalue]
+            if ndigits >= 0:
+                endpos = len(buf) - 1
+            else:
+                endpos = len(buf) + ndigits
+            # Sanity checks: there should be exactly ndigits+1 places
+            # following the decimal point, and the last digit in the
+            # buffer should be a '5'
+            if not objectmodel.we_are_translated():
+                assert buf[endpos] == '5'
+                if '.' in buf:
+                    assert endpos == len(buf) - 1
+                    assert buf.index('.') == len(buf) - ndigits - 2
+
+            # increment and shift right at the same time
+            i = endpos - 1
+            carry = 1
+            while i >= 0:
+                digit = ord(buf[i])
+                if digit == ord('.'):
+                    buf[i+1] = chr(digit)
+                    i -= 1
+                    digit = ord(buf[i])
+
+                carry += digit - ord('0')
+                buf[i+1] = chr(carry % 10 + ord('0'))
+                carry /= 10
+                i -= 1
+            buf[0] = chr(carry + ord('0'))
+            if ndigits < 0:
+                buf.append('0')
+
+            strvalue = ''.join(buf)
+
+        return sign * rstring_to_float(strvalue)
+
+else:
+    # fallback version, to be used when correctly rounded
+    # binary<->decimal conversions aren't available
+    def round_double(value, ndigits):
+        if ndigits >= 0:
+            if ndigits > 22:
+                # pow1 and pow2 are each safe from overflow, but
+                # pow1*pow2 ~= pow(10.0, ndigits) might overflow
+                pow1 = math.pow(10.0, ndigits - 22)
+                pow2 = 1e22
+            else:
+                pow1 = math.pow(10.0, ndigits)
+                pow2 = 1.0
+
+            y = (value * pow1) * pow2
+            # if y overflows, then rounded value is exactly x
+            if isinf(y):
+                return value
+
+        else:
+            pow1 = math.pow(10.0, -ndigits);
+            pow2 = 1.0 # unused; for translation
+            y = value / pow1
+
+        if y >= 0.0:
+            z = math.floor(y + 0.5)
+        else:
+            z = math.ceil(y - 0.5)
+        if math.fabs(y-z) == 1.0:   # obscure case, see the test
+            z = y
+
+        if ndigits >= 0:
+            z = (z / pow2) / pow1
+        else:
+            z *= pow1
+        return z
+
+INFINITY = 1e200 * 1e200
+NAN = INFINITY / INFINITY
+
+try:
+    # Try to get math functions added in 2.6.
+    from math import isinf, isnan, copysign, acosh, asinh, atanh, log1p
+except ImportError:
+    def isinf(x):
+        "NOT_RPYTHON"
+        return x == INFINITY or x == -INFINITY
+
+    def isnan(v):
+        "NOT_RPYTHON"
+        return v != v
+
+    def copysign(x, y):
+        """NOT_RPYTHON. Return x with the sign of y"""
+        if x < 0.:
+            x = -x
+        if y > 0. or (y == 0. and math.atan2(y, -1.) > 0.):
+            return x
+        else:
+            return -x
+
+    _2_to_m28 = 3.7252902984619141E-09; # 2**-28
+    _2_to_p28 = 268435456.0; # 2**28
+    _ln2 = 6.93147180559945286227E-01
+
+    def acosh(x):
+        "NOT_RPYTHON"
+        if isnan(x):
+            return NAN
+        if x < 1.:
+            raise ValueError("math domain error")
+        if x >= _2_to_p28:
+            if isinf(x):
+                return x
+            else:
+                return math.log(x) + _ln2
+        if x == 1.:
+            return 0.
+        if x >= 2.:
+            t = x * x
+            return math.log(2. * x - 1. / (x + math.sqrt(t - 1.0)))
+        t = x - 1.0
+        return log1p(t + math.sqrt(2. * t + t * t))
+
+    def asinh(x):
+        "NOT_RPYTHON"
+        absx = abs(x)
+        if isnan(x) or isinf(x):
+            return x
+        if absx < _2_to_m28:
+            return x
+        if absx > _2_to_p28:
+            w = math.log(absx) + _ln2
+        elif absx > 2.:
+            w = math.log(2. * absx + 1. / (math.sqrt(x * x + 1.) + absx))
+        else:
+            t = x * x
+            w = log1p(absx + t / (1. + math.sqrt(1. + t)))
+        return copysign(w, x)
+
+    def atanh(x):
+        "NOT_RPYTHON"
+        if isnan(x):
+            return x
+        absx = abs(x)
+        if absx >= 1.:
+            raise ValueError("math domain error")
+        if absx < _2_to_m28:
+            return x
+        if absx < .5:
+            t = absx + absx
+            t = .5 * log1p(t + t * absx / (1. - absx))
+        else:
+            t = .5 * log1p((absx + absx) / (1. - absx))
+        return copysign(t, x)
+
+    def log1p(x):
+        "NOT_RPYTHON"
+        from pypy.rlib import rfloat
+        if abs(x) < rfloat.DBL_EPSILON // 2.:
+            return x
+        elif -.5 <= x <= 1.:
+            y = 1. + x
+            return math.log(y) - ((y - 1.) - x) / y
+        else:
+            return math.log(1. + x)
+
+try:
+    from math import expm1 # Added in Python 2.7.
+except ImportError:
+    def expm1(x):
+        "NOT_RPYTHON"
+        if abs(x) < .7:
+            u = math.exp(x)
+            if u == 1.:
+                return x
+            return (u - 1.) * x / math.log(u)
+        return math.exp(x) - 1.
+
+def round_away(x):
+    # round() from libm, which is not available on all platforms!
+    absx = abs(x)
+    if absx - math.floor(absx) >= .5:
+        r = math.ceil(absx)
+    else:
+        r = math.floor(absx)
+    return copysign(r, x)
+

pypy/rlib/rmarshal.py

 from pypy.annotation.signature import annotation
 from pypy.annotation.listdef import ListDef, TooLateForChange
 from pypy.tool.pairtype import pair, pairtype
-from pypy.rlib.rarithmetic import formatd, r_longlong, intmask, LONG_BIT
-from pypy.rlib.rarithmetic import rstring_to_float
+from pypy.rlib.rarithmetic import r_longlong, intmask, LONG_BIT
+from pypy.rlib.rfloat import formatd, rstring_to_float
 from pypy.rlib.unroll import unrolling_iterable
 
 class CannotMarshal(Exception):

pypy/rlib/rstruct/ieee.py

 
 import math
 
-from pypy.rlib import rarithmetic, objectmodel
+from pypy.rlib import rarithmetic, rfloat, objectmodel
 from pypy.rlib.rarithmetic import r_ulonglong
 
 
 
     if exp == MAX_EXP - MIN_EXP + 2:
         # nan or infinity
-        result = rarithmetic.NAN if mant else rarithmetic.INFINITY
+        result = rfloat.NAN if mant else rfloat.INFINITY
     elif exp == 0:
         # subnormal or zero
         result = math.ldexp(mant, MIN_EXP - MANT_DIG)
     else:
         raise ValueError("invalid size value")
 
-    sign = rarithmetic.copysign(1.0, x) < 0.0
-    if rarithmetic.isinf(x):
+    sign = rfloat.copysign(1.0, x) < 0.0
+    if rfloat.isinf(x):
         mant = r_ulonglong(0)
         exp = MAX_EXP - MIN_EXP + 2
-    elif rarithmetic.isnan(x):
+    elif rfloat.isnan(x):
         mant = r_ulonglong(1) << (MANT_DIG-2) # other values possible
         exp = MAX_EXP - MIN_EXP + 2
     elif x == 0.0:

pypy/rlib/rstruct/test/test_ieee.py

 import random
 import struct
 
-from pypy.rlib.rarithmetic import isnan
+from pypy.rlib.rfloat import isnan
 from pypy.rlib.rstruct.ieee import float_pack, float_unpack
 
 

pypy/rlib/test/test_objectmodel.py

     assert compute_hash(None) == 0
 
 def test_compute_hash_float():
-    from pypy.rlib.rarithmetic import INFINITY, NAN
+    from pypy.rlib.rfloat import INFINITY, NAN
     assert compute_hash(INFINITY) == 314159
     assert compute_hash(-INFINITY) == -271828
     assert compute_hash(NAN) == 0
                     compute_hash(("world", None, 42, 7.5)))
             q = Foo()
             assert compute_hash(q) == compute_identity_hash(q)
-            from pypy.rlib.rarithmetic import INFINITY, NAN
+            from pypy.rlib.rfloat import INFINITY, NAN
             assert compute_hash(INFINITY) == 314159
             assert compute_hash(-INFINITY) == -271828
             assert compute_hash(NAN) == 0

pypy/rlib/test/test_rarithmetic.py

     assert type(abs(r_longlong(1))) is r_longlong
 
 
-def test_break_up_float():
-    assert break_up_float('1') == ('', '1', '', '')
-    assert break_up_float('+1') == ('+', '1', '', '')
-    assert break_up_float('-1') == ('-', '1', '', '')
-
-    assert break_up_float('.5') == ('', '', '5', '')
-    
-    assert break_up_float('1.2e3') == ('', '1', '2', '3')
-    assert break_up_float('1.2e+3') == ('', '1', '2', '+3')
-    assert break_up_float('1.2e-3') == ('', '1', '2', '-3')
-
-    # some that will get thrown out on return:
-    assert break_up_float('.') == ('', '', '', '')
-    assert break_up_float('+') == ('+', '', '', '')
-    assert break_up_float('-') == ('-', '', '', '')
-    assert break_up_float('e1') == ('', '', '', '1')
-
-    py.test.raises(ValueError, break_up_float, 'e')
-
 def test_r_singlefloat():
     x = r_singlefloat(2.5)       # exact number
     assert float(x) == 2.5
     py.test.raises(TypeError, "x>y")
 
 class BaseTestRarithmetic(BaseRtypingTest):
-    def test_formatd(self):
-        from pypy.rlib.rarithmetic import formatd
-        def f(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):
-        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_huge(self):
-        def f(x):
-            return formatd(x, 'f', 1234, 0)
-        res = self.ll_to_string(self.interpret(f, [1.0]))
-        assert res == '1.' + 1234 * '0'
-
-    def test_formatd_F(self):
-        from pypy.translator.c.test.test_genc import compile
-        from pypy.rlib.rarithmetic import formatd
-
-        def func(x):
-            # Test the %F format, which is not supported by
-            # the Microsoft's msvcrt library.
-            return formatd(x, 'F', 4)
-
-        f = compile(func, [float])
-        assert f(10/3.0) == '3.3333'
-
-    def test_parts_to_float(self):
-        from pypy.rlib.rarithmetic import parts_to_float, break_up_float
-        def f(x):
-            if x == 0:
-                s = '1.0'
-            else:
-                s = '1e-100'
-            sign, beforept, afterpt, expt = break_up_float(s)   
-            return parts_to_float(sign, beforept, afterpt, expt)
-        res = self.interpret(f, [0])
-        assert res == 1.0
-
-        res = self.interpret(f, [1])
-        assert res == 1e-100
-
-    def test_string_to_float(self):
-        from pypy.rlib.rarithmetic import rstring_to_float
-        def func(x):
-            if x == 0:
-                s = '1e23'
-            else:
-                s = '-1e23'
-            return rstring_to_float(s)
-
-        assert self.interpret(func, [0]) == 1e23
-        assert self.interpret(func, [1]) == -1e23
-
     def test_compare_singlefloat_crashes(self):
         from pypy.rlib.rarithmetic import r_singlefloat
         from pypy.rpython.error import MissingRTypeOperation
             return a == b
         py.test.raises(MissingRTypeOperation, "self.interpret(f, [42.0])")
 
-
 class TestLLtype(BaseTestRarithmetic, LLRtypeMixin):
     pass
 
 class TestOOtype(BaseTestRarithmetic, OORtypeMixin):
-    def test_formatd(self):
-        skip('formatd is broken on ootype')
-
-    def test_formatd_repr(self):
-        skip('formatd is broken on ootype')
-
-    def test_formatd_huge(self):
-        skip('formatd is broken on ootype')
-
-    def test_string_to_float(self):
-        skip('string_to_float is broken on ootype')
-
-def test_isinf():
-    assert isinf(INFINITY)
-
-def test_isnan():
-    assert isnan(NAN)
+    pass
 
 def test_int_real_union():
     from pypy.rpython.lltypesystem.rffi import r_int_real
     for i in xrange(31):
         assert highest_bit(2**i) == i
 
-def test_copysign():
-    assert copysign(1, 1) == 1
-    assert copysign(-1, 1) == 1
-    assert copysign(-1, -1) == -1
-    assert copysign(1, -1) == -1
-    assert copysign(1, -0.) == -1
-
-def test_round_away():
-    assert round_away(.1) == 0.
-    assert round_away(.5) == 1.
-    assert round_away(.7) == 1.
-    assert round_away(1.) == 1.
-    assert round_away(-.5) == -1.
-    assert round_away(-.1) == 0.
-    assert round_away(-.7) == -1.
-    assert round_away(0.) == 0.
-
-def test_round_double():
-    def almost_equal(x, y):
-        assert round(abs(x-y), 7) == 0
-
-    almost_equal(round_double(0.125, 2), 0.13)
-    almost_equal(round_double(0.375, 2), 0.38)
-    almost_equal(round_double(0.625, 2), 0.63)
-    almost_equal(round_double(0.875, 2), 0.88)
-    almost_equal(round_double(-0.125, 2), -0.13)
-    almost_equal(round_double(-0.375, 2), -0.38)
-    almost_equal(round_double(-0.625, 2), -0.63)
-    almost_equal(round_double(-0.875, 2), -0.88)
-
-    almost_equal(round_double(0.25, 1), 0.3)
-    almost_equal(round_double(0.75, 1), 0.8)
-    almost_equal(round_double(-0.25, 1), -0.3)
-    almost_equal(round_double(-0.75, 1), -0.8)
-
-    round_double(-6.5, 0) == -7.0
-    round_double(-5.5, 0) == -6.0
-    round_double(-1.5, 0) == -2.0
-    round_double(-0.5, 0) == -1.0
-    round_double(0.5, 0) == 1.0
-    round_double(1.5, 0) == 2.0
-    round_double(2.5, 0) == 3.0
-    round_double(3.5, 0) == 4.0
-    round_double(4.5, 0) == 5.0
-    round_double(5.5, 0) == 6.0
-    round_double(6.5, 0) == 7.0
-
-    round_double(-25.0, -1) == -30.0
-    round_double(-15.0, -1) == -20.0
-    round_double(-5.0, -1) == -10.0
-    round_double(5.0, -1) == 10.0
-    round_double(15.0, -1) == 20.0
-    round_double(25.0, -1) == 30.0
-    round_double(35.0, -1) == 40.0
-    round_double(45.0, -1) == 50.0
-    round_double(55.0, -1) == 60.0
-    round_double(65.0, -1) == 70.0
-    round_double(75.0, -1) == 80.0
-    round_double(85.0, -1) == 90.0
-    round_double(95.0, -1) == 100.0
-    round_double(12325.0, -1) == 12330.0
-
-    round_double(350.0, -2) == 400.0
-    round_double(450.0, -2) == 500.0
-
-    almost_equal(round_double(0.5e21, -21), 1e21)
-    almost_equal(round_double(1.5e21, -21), 2e21)
-    almost_equal(round_double(2.5e21, -21), 3e21)
-    almost_equal(round_double(5.5e21, -21), 6e21)
-    almost_equal(round_double(8.5e21, -21), 9e21)
-
-    almost_equal(round_double(-1.5e22, -22), -2e22)
-    almost_equal(round_double(-0.5e22, -22), -1e22)
-    almost_equal(round_double(0.5e22, -22), 1e22)
-    almost_equal(round_double(1.5e22, -22), 2e22)
-
 def test_int_between():
     assert int_between(1, 1, 3)
     assert int_between(1, 2, 3)

pypy/rlib/test/test_rdtoa.py

 from pypy.rlib.rdtoa import strtod, dtoa
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 
 def test_strtod():
     assert strtod("12345") == 12345.0
     assert dtoa(3.47) == "3.47"
     assert dtoa(1.1) == "1.1"
     assert dtoa(-1.1) == "-1.1"
-    assert dtoa(1.1, flags=rarithmetic.DTSF_SIGN) == "+1.1"
+    assert dtoa(1.1, flags=rfloat.DTSF_SIGN) == "+1.1"
     assert dtoa(12.3577) == "12.3577"
     assert dtoa(10.0) == "10"
     assert dtoa(1.0e100) == "1e+100"
 
-    assert dtoa(rarithmetic.INFINITY) == 'inf'
-    assert dtoa(-rarithmetic.INFINITY) == '-inf'
-    assert dtoa(rarithmetic.NAN) == 'nan'
+    assert dtoa(rfloat.INFINITY) == 'inf'
+    assert dtoa(-rfloat.INFINITY) == '-inf'
+    assert dtoa(rfloat.NAN) == 'nan'
 
 def test_dtoa_precision():
     assert dtoa(1.1, code='f', precision=2) == "1.10"

pypy/rlib/test/test_rmarshal.py

 import marshal
 from pypy.rlib.rmarshal import *
 from pypy.annotation import model as annmodel
-from pypy.rlib.rarithmetic import formatd, LONG_BIT
+from pypy.rlib.rarithmetic import LONG_BIT
+from pypy.rlib.rfloat import formatd
 
 types_that_can_be_none = [
     [int],

pypy/rlib/test/test_rstruct.py

 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 from pypy.rlib.rstruct.runpack import runpack
 from pypy.rlib.rstruct import ieee
-from pypy.rlib.rarithmetic import LONG_BIT, INFINITY, NAN, isnan
+from pypy.rlib.rarithmetic import LONG_BIT
+from pypy.rlib.rfloat import INFINITY, NAN, isnan
 from pypy.translator.c.test.test_genc import compile
 import struct
 

pypy/rpython/extfuncregistry.py

 from pypy.rpython.ootypesystem.module import ll_math as oo_math
 from pypy.rpython.module import ll_os
 from pypy.rpython.module import ll_time
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 try:
     import termios
 except ImportError:
     try:
         f = getattr(math, name)
     except AttributeError:
-        f = getattr(rarithmetic, name)
+        f = getattr(rfloat, name)
     register_external(f, [float], float,
                       export_name="ll_math.ll_math_%s" % name,
                        sandboxsafe=True, llimpl=llimpl)
 
-register_external(rarithmetic.isinf, [float], bool,
+register_external(rfloat.isinf, [float], bool,
                   export_name="ll_math.ll_math_isinf", sandboxsafe=True,
                   llimpl=ll_math.ll_math_isinf)
-register_external(rarithmetic.isnan, [float], bool,
+register_external(rfloat.isnan, [float], bool,
                   export_name="ll_math.ll_math_isnan", sandboxsafe=True,
                   llimpl=ll_math.ll_math_isnan)
-register_external(rarithmetic.copysign, [float, float], float,
+register_external(rfloat.copysign, [float, float], float,
                   export_name="ll_math.ll_math_copysign", sandboxsafe=True,
                   llimpl=ll_math.ll_math_copysign)
 

pypy/rpython/lltypesystem/ll_str.py

 from pypy.rpython.lltypesystem.lltype import GcArray, Array, Char, malloc
 from pypy.rpython.annlowlevel import llstr
-from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, formatd
+from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong
 
 CHAR_ARRAY = GcArray(Char)
 
 ll_int2oct._pure_function_ = True
 
 def ll_float_str(repr, f):
+    from pypy.rlib.rfloat import formatd
     return llstr(formatd(f, 'f', 6))
 ll_float_str._pure_function_ = True

pypy/rpython/lltypesystem/module/ll_math.py

 from pypy.tool.autopath import pypydir
 from pypy.rlib import rposix
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN
+from pypy.rlib.rfloat import isinf, isnan, INFINITY, NAN
 
 if sys.platform == "win32":
     eci = ExternalCompilationInfo()

pypy/rpython/lltypesystem/module/test/test_llinterp_math.py

 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin
 from pypy.rpython.lltypesystem.module import ll_math
 import math
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 
 # XXX no OORtypeMixin here
 
             fn = getattr(math, name)
             assert_exact = True
         except AttributeError:
-            fn = getattr(rarithmetic, name)
+            fn = getattr(rfloat, name)
             assert_exact = False
         if name == 'acosh':
             value = 1.3     # acosh(x) is only defined for x >= 1.0

pypy/rpython/module/ll_strtod.py

 
 import py
 from pypy.rpython.extfunc import BaseLazyRegistering, extdef, registering
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.tool.autopath import pypydir
 from pypy.rpython.ootypesystem import ootype
     def __init__(self):
         self.configure(CConfig)
     
-    @registering(rarithmetic._formatd)
+    @registering(rfloat._formatd)
     def register_formatd(self):
         ll_strtod = self.llexternal('LL_strtod_formatd',
                                     [rffi.DOUBLE, rffi.CHAR, rffi.INT], rffi.CCHARP,
             res = ll_strtod(x, code, precision)
             s = rffi.charp2str(res)
 
-            if flags & rarithmetic.DTSF_ADD_DOT_0:
+            if flags & rfloat.DTSF_ADD_DOT_0:
                 s = ensure_decimal_point(s, precision)
 
             # Add sign when requested
-            if flags & rarithmetic.DTSF_SIGN and s[0] != '-':
+            if flags & rfloat.DTSF_SIGN and s[0] != '-':
                 s = '+' + s
 
             # Convert to upper case
             return s
 
         def oofakeimpl(x, code, precision, flags):
-            return ootype.oostring(rarithmetic.formatd(x, code, precision, flags), -1)
+            return ootype.oostring(rfloat.formatd(x, code, precision, flags), -1)
 
         return extdef([float, lltype.Char, int, int], str, 'll_strtod.ll_strtod_formatd',
                       llimpl=llimpl, oofakeimpl=oofakeimpl,
                       sandboxsafe=True)
 
-    @registering(rarithmetic.parts_to_float)
+    @registering(rfloat.parts_to_float)
     def register_parts_to_float(self):
         ll_parts_to_float = self.llexternal('LL_strtod_parts_to_float',
                                             [rffi.CCHARP] * 4, rffi.DOUBLE,
             return res
 
         def oofakeimpl(sign, beforept, afterpt, exponent):
-            return rarithmetic.parts_to_float(sign._str, beforept._str,
-                                              afterpt._str, exponent._str)
+            return rfloat.parts_to_float(sign._str, beforept._str,
+                                         afterpt._str, exponent._str)
 
         return extdef([str, str, str, str], float,
                       'll_strtod.ll_strtod_parts_to_float', llimpl=llimpl,

pypy/rpython/module/test/test_ll_strtod.py

 import py
 
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 
 class BaseTestStrtod(BaseRtypingTest):    
     def test_formatd(self):
         for flags in [0,
-                      rarithmetic.DTSF_ADD_DOT_0]:
+                      rfloat.DTSF_ADD_DOT_0]:
             def f(y):
-                return rarithmetic.formatd(y, 'g', 2, flags)
+                return rfloat.formatd(y, 'g', 2, flags)
 
             assert self.ll_to_string(self.interpret(f, [3.0])) == f(3.0)
 
         def f(a, b, c, d):
             a,b,c,d = hlstr(a), hlstr(b), hlstr(c), hlstr(d)
             
-            return rarithmetic.parts_to_float(a, b, c, d)
+            return rfloat.parts_to_float(a, b, c, d)
         
         data = [
         (("","1","","")     , 1.0),

pypy/rpython/rstr.py

 
     def ll_float(ll_str):
         from pypy.rpython.annlowlevel import hlstr
-        from pypy.rlib.rarithmetic import rstring_to_float
+        from pypy.rlib.rfloat import rstring_to_float
         s = hlstr(ll_str)
         assert s is not None
 

pypy/rpython/tool/test/test_rffi_platform.py

 from pypy.tool.udir import udir
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.translator.platform import platform
-from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, isnan
+from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong
+from pypy.rlib.rfloat import isnan
 
 def import_ctypes():
     try:
         # we also have to avoid confusing 0.0 and -0.0 (needed e.g. for
         # translating the cmath module)
         if key[0] is float and not self.value:
-            from pypy.rlib.rarithmetic import copysign
+            from pypy.rlib.rfloat import copysign
             if copysign(1., self.value) == -1.:    # -0.0
                 key = (float, "-0.0")
         #

pypy/translator/c/node.py

 from pypy.translator.c.support import c_char_array_constant, barebonearray
 from pypy.translator.c.primitive import PrimitiveType, name_signed
 from pypy.rlib import exports
-from pypy.rlib.rarithmetic import isinf, isnan
+from pypy.rlib.rfloat import isinf, isnan
 from pypy.rlib.rstackovf import _StackOverflow
 from pypy.translator.c import extfunc
 from pypy.translator.tool.cbuild import ExternalCompilationInfo

pypy/translator/c/primitive.py

 import sys
 from pypy.rlib.objectmodel import Symbolic, ComputedIntSymbolic
 from pypy.rlib.objectmodel import CDefinedIntSymbolic
-from pypy.rlib.rarithmetic import r_longlong, isinf, isnan
+from pypy.rlib.rarithmetic import r_longlong
+from pypy.rlib.rfloat import isinf, isnan
 from pypy.rpython.lltypesystem.lltype import *
 from pypy.rpython.lltypesystem import rffi, llgroup
 from pypy.rpython.lltypesystem.llmemory import Address, \

pypy/translator/c/test/test_extfunc.py

     assert t0 <= res <= t1
 
 
-def test_rarith_parts_to_float():
-    from pypy.rlib.rarithmetic import parts_to_float
+def test_parts_to_float():
+    from pypy.rlib.rfloat import parts_to_float
     def fn(sign, beforept, afterpt, exponent):
         return parts_to_float(sign, beforept, afterpt, exponent)
 
     for parts, val in data:
         assert f(*parts) == val
 
-def test_rarith_formatd():
-    from pypy.rlib.rarithmetic import formatd
+def test_formatd():
+    from pypy.rlib.rfloat import formatd
     def fn(x):
         return formatd(x, 'f', 2, 0)
 
     assert f(1.5) == "1.50"
     assert f(2.0) == "2.00"
 
-def test_rarith_float_to_str():
+def test_float_to_str():
     def fn(f):
         return str(f)
     f = compile(fn, [float])

pypy/translator/c/test/test_math.py

 import py, math
 from pypy.module.math.test import test_direct
 from pypy.translator.c.test.test_standalone import StandaloneTests
-from pypy.rlib import rarithmetic
+from pypy.rlib import rfloat
 
 
 def get_test_case((fnname, args, expected)):
     try:
         fn = getattr(math, fnname)
     except AttributeError:
-        fn = getattr(rarithmetic, fnname)
+        fn = getattr(rfloat, fnname)
     expect_valueerror = (expected == ValueError)
     expect_overflowerror = (expected == OverflowError)
     check = test_direct.get_tester(expected)

pypy/translator/cli/ilgenerator.py

 from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong
 from pypy.rpython.lltypesystem import rffi
 from pypy.rlib.objectmodel import CDefinedIntSymbolic
-from pypy.rlib.rarithmetic import isnan, isinf
+from pypy.rlib.rfloat import isnan, isinf
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.oosupport.metavm import Generator
 from pypy.translator.oosupport.constant import push_constant

pypy/translator/jvm/generator.py

 from pypy.translator.oosupport.function import render_sub_op
 from pypy.rpython.ootypesystem import ootype
 from pypy.rlib.objectmodel import CDefinedIntSymbolic
-from pypy.rlib.rarithmetic import isnan, isinf
+from pypy.rlib.rfloat import isnan, isinf
 from pypy.translator.oosupport.constant import push_constant
 import pypy.translator.jvm.typesystem as jvm
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.