Exemple #1
0
def _round_float(space, w_float, w_ndigits=None):
    # Algorithm copied directly from CPython
    x = w_float.floatval

    if w_ndigits is None:
        # single-argument round: round to nearest integer
        rounded = rfloat.round_away(x)
        if math.fabs(x - rounded) == 0.5:
            # halfway case: round to even
            rounded = 2.0 * rfloat.round_away(x / 2.0)
        return newlong_from_float(space, rounded)

    # interpret 2nd argument as a Py_ssize_t; clip on overflow
    ndigits = space.getindex_w(w_ndigits, None)

    # nans and infinities round to themselves
    if not rfloat.isfinite(x):
        return space.wrap(x)

    # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
    # always rounds to itself.  For ndigits < NDIGITS_MIN, x always
    # rounds to +-0.0
    if ndigits > NDIGITS_MAX:
        return space.wrap(x)
    elif ndigits < NDIGITS_MIN:
        # return 0.0, but with sign of x
        return space.wrap(0.0 * x)

    # finite x, and ndigits is not unreasonably large
    z = rfloat.round_double(x, ndigits, half_even=True)
    if rfloat.isinf(z):
        raise oefmt(space.w_OverflowError, "overflow occurred during round")
    return space.wrap(z)
def _round_float(space, w_float, w_ndigits=None):
    # Algorithm copied directly from CPython
    x = w_float.floatval

    if w_ndigits is None:
        # single-argument round: round to nearest integer
        rounded = rfloat.round_away(x)
        if math.fabs(x - rounded) == 0.5:
            # halfway case: round to even
            rounded = 2.0 * rfloat.round_away(x / 2.0)
        return newlong_from_float(space, rounded)

    # interpret 2nd argument as a Py_ssize_t; clip on overflow
    ndigits = space.getindex_w(w_ndigits, None)

    # nans and infinities round to themselves
    if not rfloat.isfinite(x):
        return space.newfloat(x)

    # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
    # always rounds to itself.  For ndigits < NDIGITS_MIN, x always
    # rounds to +-0.0
    if ndigits > NDIGITS_MAX:
        return space.newfloat(x)
    elif ndigits < NDIGITS_MIN:
        # return 0.0, but with sign of x
        return space.newfloat(0.0 * x)

    # finite x, and ndigits is not unreasonably large
    z = rfloat.round_double(x, ndigits, half_even=True)
    if math.isinf(z):
        raise oefmt(space.w_OverflowError, "overflow occurred during round")
    return space.newfloat(z)
Exemple #3
0
def round(space, number, w_ndigits):
    """round(number[, ndigits]) -> floating point number

Round a number to a given precision in decimal digits (default 0 digits).
This always returns a floating point number.  Precision may be negative."""
    # Algorithm copied directly from CPython

    # interpret 2nd argument as a Py_ssize_t; clip on overflow
    ndigits = space.getindex_w(w_ndigits, None)

    # nans, infinities and zeros round to themselves
    if not isfinite(number):
        z = number
    elif ndigits == 0:  # common case
        z = round_away(number)
        # no need to check for an infinite 'z' here
    else:
        # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
        # always rounds to itself.  For ndigits < NDIGITS_MIN, x always
        # rounds to +-0.0.
        if ndigits > NDIGITS_MAX:
            z = number
        elif ndigits < NDIGITS_MIN:
            # return 0.0, but with sign of x
            z = 0.0 * number
        else:
            # finite x, and ndigits is not unreasonably large
            z = round_double(number, ndigits)
            if isinf(z):
                raise oefmt(space.w_OverflowError,
                            "rounded value too large to represent")
    return space.newfloat(z)
Exemple #4
0
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.
Exemple #5
0
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.
Exemple #6
0
 def method_divmod(self, space, w_other):
     if math.isnan(self.floatvalue) or math.isinf(self.floatvalue):
         raise space.error(
             space.w_FloatDomainError,
             space.obj_to_s(space.getclass(w_other))
         )
     if (space.is_kind_of(w_other, space.w_fixnum) or
         space.is_kind_of(w_other, space.w_bignum) or
         space.is_kind_of(w_other, space.w_float)):
         y = space.float_w(w_other)
         if math.isnan(y):
             raise space.error(
                 space.w_FloatDomainError,
                 space.obj_to_s(space.getclass(w_other))
             )
         x = self.floatvalue
         mod = space.float_w(self.method_mod_float_impl(space, y))
         # TAKEN FROM: pypy/module/cpytext/floatobject.py
         div = (x - mod) / y
         if (mod):
             # ensure the remainder has the same sign as the denominator
             if ((y < 0.0) != (mod < 0.0)):
                 mod += y
                 div -= 1.0
         else:
             mod *= mod  # hide "mod = +0" from optimizer
             if y < 0.0:
                 mod = -mod
         # snap quotient to nearest integral value
         if div:
             floordiv = math.floor(div)
             if (div - floordiv > 0.5):
                 floordiv += 1.0
         else:
             # div is zero - get the same sign as the true quotient
             div *= div  # hide "div = +0" from optimizers
             floordiv = div * x / y  # zero w/ sign of vx/wx
         try:
             return space.newarray([self.float_to_w_int(space, round_away(div)), space.newfloat(mod)])
         except OverflowError:
             return space.newarray([space.newbigint_fromfloat(div), space.newfloat(mod)])
     else:
         raise space.error(
             space.w_TypeError,
             "%s can't be coerced into Float" % (
                 space.obj_to_s(space.getclass(w_other))
             )
         )
Exemple #7
0
 def method_divmod(self, space, w_other):
     if math.isnan(self.floatvalue) or math.isinf(self.floatvalue):
         raise space.error(
             space.w_FloatDomainError,
             space.obj_to_s(space.getclass(w_other))
         )
     if (space.is_kind_of(w_other, space.w_fixnum) or
         space.is_kind_of(w_other, space.w_bignum) or
         space.is_kind_of(w_other, space.w_float)):
         y = space.float_w(w_other)
         if math.isnan(y):
             raise space.error(
                 space.w_FloatDomainError,
                 space.obj_to_s(space.getclass(w_other))
             )
         x = self.floatvalue
         mod = space.float_w(self.method_mod_float_impl(space, y))
         # TAKEN FROM: pypy/module/cpytext/floatobject.py
         div = (x - mod) / y
         if (mod):
             # ensure the remainder has the same sign as the denominator
             if ((y < 0.0) != (mod < 0.0)):
                 mod += y
                 div -= 1.0
         else:
             mod *= mod  # hide "mod = +0" from optimizer
             if y < 0.0:
                 mod = -mod
         # snap quotient to nearest integral value
         if div:
             floordiv = math.floor(div)
             if (div - floordiv > 0.5):
                 floordiv += 1.0
         else:
             # div is zero - get the same sign as the true quotient
             div *= div  # hide "div = +0" from optimizers
             floordiv = div * x / y  # zero w/ sign of vx/wx
         try:
             return space.newarray([self.float_to_w_int(space, round_away(div)), space.newfloat(mod)])
         except OverflowError:
             return space.newarray([space.newbigint_fromfloat(div), space.newfloat(mod)])
     else:
         raise space.error(
             space.w_TypeError,
             "%s can't be coerced into Float" % (
                 space.obj_to_s(space.getclass(w_other))
             )
         )
Exemple #8
0
 def method_divmod(self, space, w_other):
     if space.is_kind_of(w_other, space.w_float):
         return space.send(self.method_to_f(space), "divmod", [w_other])
     elif space.is_kind_of(w_other, space.w_bignum):
         return space.send(space.newbigint_fromint(self.intvalue), "divmod",
                           [w_other])
     elif space.is_kind_of(w_other, space.w_fixnum):
         y = space.int_w(w_other)
         if y == 0:
             raise space.error(space.w_ZeroDivisionError, "divided by 0")
         mod = space.int_w(self.method_mod_int_impl(space, y))
         div = (self.intvalue - mod) / y
         return space.newarray(
             [space.newint(int(round_away(div))),
              space.newfloat(mod)])
     else:
         raise space.error(
             space.w_TypeError, "%s can't be coerced into Fixnum" %
             (space.obj_to_s(space.getclass(w_other))))
Exemple #9
0
 def method_divmod(self, space, w_other):
     if space.is_kind_of(w_other, space.w_float):
         return space.send(self.method_to_f(space), "divmod", [w_other])
     elif space.is_kind_of(w_other, space.w_bignum):
         return space.send(space.newbigint_fromint(self.intvalue), "divmod", [w_other])
     elif space.is_kind_of(w_other, space.w_fixnum):
         y = space.int_w(w_other)
         if y == 0:
             raise space.error(
                 space.w_ZeroDivisionError,
                 "divided by 0"
             )
         mod = space.int_w(self.method_mod_int_impl(space, y))
         div = (self.intvalue - mod) / y
         return space.newarray([space.newint(int(round_away(div))), space.newfloat(mod)])
     else:
         raise space.error(
             space.w_TypeError,
             "%s can't be coerced into Fixnum" % (
                 space.obj_to_s(space.getclass(w_other))
             )
         )
Exemple #10
0
 def method_round(self, space):
     return space.newint(int(round_away(Coerce.float(space, self))))
Exemple #11
0
 def method_round(self, space):
     return space.newint(int(round_away(Coerce.float(space, self))))
Exemple #12
0
 def method_round(self, space):
     return space.newint(int(round_away(self.floatvalue)))
Exemple #13
0
 def method_round(self, space):
     return space.newint(int(round_away(self.floatvalue)))