Implement advanced rounding functionality in API
This commit is contained in:
parent
7b52f8f06d
commit
a3d79e993a
@ -24,6 +24,11 @@ class Fixed:
|
|||||||
Wrapper for big.js (fixed-point arithmetic)
|
Wrapper for big.js (fixed-point arithmetic)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ROUND_DOWN = 0
|
||||||
|
ROUND_HALF_UP = 1
|
||||||
|
ROUND_HALF_EVEN = 2
|
||||||
|
ROUND_UP = 3
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
if isinstance(val, Fixed):
|
if isinstance(val, Fixed):
|
||||||
self.impl = val.impl
|
self.impl = val.impl
|
||||||
@ -60,4 +65,8 @@ class Fixed:
|
|||||||
return self.impl.lte(other.impl)
|
return self.impl.lte(other.impl)
|
||||||
|
|
||||||
def __floor__(self):
|
def __floor__(self):
|
||||||
return Fixed(Math.floor(self.impl))
|
return self.round(0, Fixed.ROUND_DOWN)
|
||||||
|
|
||||||
|
def round(self, dps, mode):
|
||||||
|
"""Round to the specified number of decimal places, using the ROUND_* mode specified"""
|
||||||
|
return Fixed(self.impl.round(dps, mode))
|
||||||
|
@ -14,25 +14,39 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from decimal import Decimal
|
import decimal
|
||||||
|
import functools
|
||||||
import math
|
import math
|
||||||
|
|
||||||
_quantize_exp = 6
|
_quantize_exp = 6
|
||||||
|
|
||||||
def set_dps(dps):
|
def set_dps(dps):
|
||||||
global _quantize_exp
|
global _quantize_exp
|
||||||
_quantize_exp = Decimal('10') ** -dps
|
_quantize_exp = decimal.Decimal('10') ** -dps
|
||||||
|
|
||||||
|
def compatible_types(f):
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(self, other):
|
||||||
|
if not isinstance(other, Fixed):
|
||||||
|
raise ValueError('Attempt to operate on incompatible types')
|
||||||
|
return f(self, other)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
class Fixed:
|
class Fixed:
|
||||||
"""
|
"""
|
||||||
Wrapper for Python Decimal (for fixed-point arithmetic)
|
Wrapper for Python Decimal (for fixed-point arithmetic)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ROUND_DOWN = decimal.ROUND_DOWN
|
||||||
|
ROUND_HALF_UP = decimal.ROUND_HALF_UP
|
||||||
|
ROUND_HALF_EVEN = decimal.ROUND_HALF_EVEN
|
||||||
|
ROUND_UP = decimal.ROUND_UP
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
if isinstance(val, Fixed):
|
if isinstance(val, Fixed):
|
||||||
self.impl = val.impl
|
self.impl = val.impl
|
||||||
else:
|
else:
|
||||||
self.impl = Decimal(val).quantize(_quantize_exp)
|
self.impl = decimal.Decimal(val).quantize(_quantize_exp)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Fixed {}>'.format(str(self.impl))
|
return '<Fixed {}>'.format(str(self.impl))
|
||||||
@ -45,43 +59,38 @@ class Fixed:
|
|||||||
from pyRCV2.numbers import Rational
|
from pyRCV2.numbers import Rational
|
||||||
return Rational(self.impl)
|
return Rational(self.impl)
|
||||||
|
|
||||||
|
@compatible_types
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Fixed(self.impl + other.impl)
|
return Fixed(self.impl + other.impl)
|
||||||
|
@compatible_types
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Fixed(self.impl - other.impl)
|
return Fixed(self.impl - other.impl)
|
||||||
|
@compatible_types
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Fixed(self.impl * other.impl)
|
return Fixed(self.impl * other.impl)
|
||||||
|
@compatible_types
|
||||||
def __truediv__(self, other):
|
def __truediv__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Fixed(self.impl / other.impl)
|
return Fixed(self.impl / other.impl)
|
||||||
|
|
||||||
|
@compatible_types
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl == other.impl
|
return self.impl == other.impl
|
||||||
|
@compatible_types
|
||||||
def __gt__(self, other):
|
def __gt__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl > other.impl
|
return self.impl > other.impl
|
||||||
|
@compatible_types
|
||||||
def __ge__(self, other):
|
def __ge__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl >= other.impl
|
return self.impl >= other.impl
|
||||||
|
@compatible_types
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl < other.impl
|
return self.impl < other.impl
|
||||||
|
@compatible_types
|
||||||
def __le__(self, other):
|
def __le__(self, other):
|
||||||
if not isinstance(other, Fixed):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl <= other.impl
|
return self.impl <= other.impl
|
||||||
|
|
||||||
def __floor__(self):
|
def __floor__(self):
|
||||||
return Fixed(math.floor(self.impl))
|
return Fixed(math.floor(self.impl))
|
||||||
|
|
||||||
|
def round(self, dps, mode):
|
||||||
|
"""Round to the specified number of decimal places, using the ROUND_* mode specified"""
|
||||||
|
return Fixed(self.impl.quantize(decimal.Decimal('10') ** -dps, mode))
|
||||||
|
@ -19,6 +19,11 @@ class Native:
|
|||||||
Wrapper for JS numbers (naive floating-point arithmetic)
|
Wrapper for JS numbers (naive floating-point arithmetic)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ROUND_DOWN = 0
|
||||||
|
ROUND_HALF_UP = 1
|
||||||
|
ROUND_HALF_EVEN = 2
|
||||||
|
ROUND_UP = 3
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
if isinstance(val, Native):
|
if isinstance(val, Native):
|
||||||
self.impl = val.impl
|
self.impl = val.impl
|
||||||
@ -56,3 +61,16 @@ class Native:
|
|||||||
|
|
||||||
def __floor__(self):
|
def __floor__(self):
|
||||||
return Native(Math.floor(self.impl))
|
return Native(Math.floor(self.impl))
|
||||||
|
|
||||||
|
def round(self, dps, mode):
|
||||||
|
"""Round to the specified number of decimal places, using the ROUND_* mode specified"""
|
||||||
|
if mode == Native.ROUND_DOWN:
|
||||||
|
return Native(Math.floor(self.impl * Math.pow(10, dps)) / Math.pow(10, dps))
|
||||||
|
elif mode == Native.ROUND_HALF_UP:
|
||||||
|
return Native(Math.round(self.impl * Math.pow(10, dps)) / Math.pow(10, dps))
|
||||||
|
elif mode == Native.ROUND_HALF_EVEN:
|
||||||
|
raise Exception('ROUND_HALF_EVEN is not implemented in JS Native context')
|
||||||
|
elif mode == Native.ROUND_UP:
|
||||||
|
return Native(Math.ceil(self.impl * Math.pow(10, dps)) / Math.pow(10, dps))
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid rounding mode')
|
||||||
|
@ -14,13 +14,27 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import functools
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
def compatible_types(f):
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(self, other):
|
||||||
|
if not isinstance(other, Native):
|
||||||
|
raise ValueError('Attempt to operate on incompatible types')
|
||||||
|
return f(self, other)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
class Native:
|
class Native:
|
||||||
"""
|
"""
|
||||||
Wrapper for Python float (naive floating-point arithmetic)
|
Wrapper for Python float (naive floating-point arithmetic)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ROUND_DOWN = 0
|
||||||
|
ROUND_HALF_UP = 1
|
||||||
|
ROUND_HALF_EVEN = 2
|
||||||
|
ROUND_UP = 3
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
if isinstance(val, Native):
|
if isinstance(val, Native):
|
||||||
self.impl = val.impl
|
self.impl = val.impl
|
||||||
@ -38,43 +52,48 @@ class Native:
|
|||||||
from pyRCV2.numbers import Rational
|
from pyRCV2.numbers import Rational
|
||||||
return Rational(self.impl)
|
return Rational(self.impl)
|
||||||
|
|
||||||
|
@compatible_types
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Native(self.impl + other.impl)
|
return Native(self.impl + other.impl)
|
||||||
|
@compatible_types
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Native(self.impl - other.impl)
|
return Native(self.impl - other.impl)
|
||||||
|
@compatible_types
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Native(self.impl * other.impl)
|
return Native(self.impl * other.impl)
|
||||||
|
@compatible_types
|
||||||
def __truediv__(self, other):
|
def __truediv__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Native(self.impl / other.impl)
|
return Native(self.impl / other.impl)
|
||||||
|
|
||||||
|
@compatible_types
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl == other.impl
|
return self.impl == other.impl
|
||||||
|
@compatible_types
|
||||||
def __gt__(self, other):
|
def __gt__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl > other.impl
|
return self.impl > other.impl
|
||||||
|
@compatible_types
|
||||||
def __ge__(self, other):
|
def __ge__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl >= other.impl
|
return self.impl >= other.impl
|
||||||
|
@compatible_types
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl < other.impl
|
return self.impl < other.impl
|
||||||
|
@compatible_types
|
||||||
def __le__(self, other):
|
def __le__(self, other):
|
||||||
if not isinstance(other, Native):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl <= other.impl
|
return self.impl <= other.impl
|
||||||
|
|
||||||
def __floor__(self):
|
def __floor__(self):
|
||||||
return Native(math.floor(self.impl))
|
return Native(math.floor(self.impl))
|
||||||
|
|
||||||
|
def round(self, dps, mode):
|
||||||
|
"""Round to the specified number of decimal places, using the ROUND_* mode specified"""
|
||||||
|
factor = 10 ** dps
|
||||||
|
if mode == Native.ROUND_DOWN:
|
||||||
|
return Native(math.floor(self.impl * factor) / factor)
|
||||||
|
elif mode == Native.ROUND_HALF_UP:
|
||||||
|
raise Exception('ROUND_HALF_UP is not implemented in Python Native context')
|
||||||
|
elif mode == Native.ROUND_HALF_EVEN:
|
||||||
|
return Native(round(self.impl * factor) / factor)
|
||||||
|
elif mode == Native.ROUND_UP:
|
||||||
|
return Native(math.ceil(self.impl * factor) / factor)
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid rounding mode')
|
||||||
|
@ -19,6 +19,11 @@ class Rational:
|
|||||||
Wrapper for BigRational.js (rational arithmetic)
|
Wrapper for BigRational.js (rational arithmetic)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ROUND_DOWN = 0
|
||||||
|
ROUND_HALF_UP = 1
|
||||||
|
ROUND_HALF_EVEN = 2
|
||||||
|
ROUND_UP = 3
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
if isinstance(val, Rational):
|
if isinstance(val, Rational):
|
||||||
self.impl = val.impl
|
self.impl = val.impl
|
||||||
@ -66,3 +71,17 @@ class Rational:
|
|||||||
|
|
||||||
def __floor__(self):
|
def __floor__(self):
|
||||||
return Rational(self.impl.floor())
|
return Rational(self.impl.floor())
|
||||||
|
|
||||||
|
def round(self, dps, mode):
|
||||||
|
"""Round to the specified number of decimal places, using the ROUND_* mode specified"""
|
||||||
|
factor = bigRat(10).pow(dps)
|
||||||
|
if mode == Rational.ROUND_DOWN:
|
||||||
|
return Rational(self.impl.multiply(factor).floor().divide(factor))
|
||||||
|
elif mode == Rational.ROUND_HALF_UP:
|
||||||
|
return Rational(self.impl.multiply(factor).round().divide(factor))
|
||||||
|
elif mode == Rational.ROUND_HALF_EVEN:
|
||||||
|
raise Exception('ROUND_HALF_EVEN is not implemented in JS Native context')
|
||||||
|
elif mode == Rational.ROUND_UP:
|
||||||
|
return Rational(self.impl.multiply(factor).ceil().divide(factor))
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid rounding mode')
|
||||||
|
@ -15,13 +15,27 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
|
import functools
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
def compatible_types(f):
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(self, other):
|
||||||
|
if not isinstance(other, Rational):
|
||||||
|
raise ValueError('Attempt to operate on incompatible types')
|
||||||
|
return f(self, other)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
class Rational:
|
class Rational:
|
||||||
"""
|
"""
|
||||||
Wrapper for Python Fraction (rational arithmetic)
|
Wrapper for Python Fraction (rational arithmetic)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ROUND_DOWN = 0
|
||||||
|
ROUND_HALF_UP = 1
|
||||||
|
ROUND_HALF_EVEN = 2
|
||||||
|
ROUND_UP = 3
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
if isinstance(val, Rational):
|
if isinstance(val, Rational):
|
||||||
self.impl = val.impl
|
self.impl = val.impl
|
||||||
@ -47,43 +61,48 @@ class Rational:
|
|||||||
from pyRCV2.numbers import Num
|
from pyRCV2.numbers import Num
|
||||||
return Num(self.impl.numerator) / Num(self.impl.denominator)
|
return Num(self.impl.numerator) / Num(self.impl.denominator)
|
||||||
|
|
||||||
|
@compatible_types
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Rational(self.impl + other.impl)
|
return Rational(self.impl + other.impl)
|
||||||
|
@compatible_types
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Rational(self.impl - other.impl)
|
return Rational(self.impl - other.impl)
|
||||||
|
@compatible_types
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Rational(self.impl * other.impl)
|
return Rational(self.impl * other.impl)
|
||||||
|
@compatible_types
|
||||||
def __truediv__(self, other):
|
def __truediv__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return Rational(self.impl / other.impl)
|
return Rational(self.impl / other.impl)
|
||||||
|
|
||||||
|
@compatible_types
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl == other.impl
|
return self.impl == other.impl
|
||||||
|
@compatible_types
|
||||||
def __gt__(self, other):
|
def __gt__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl > other.impl
|
return self.impl > other.impl
|
||||||
|
@compatible_types
|
||||||
def __ge__(self, other):
|
def __ge__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl >= other.impl
|
return self.impl >= other.impl
|
||||||
|
@compatible_types
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl < other.impl
|
return self.impl < other.impl
|
||||||
|
@compatible_types
|
||||||
def __le__(self, other):
|
def __le__(self, other):
|
||||||
if not isinstance(other, Rational):
|
|
||||||
raise ValueError('Attempt to operate on incompatible types')
|
|
||||||
return self.impl <= other.impl
|
return self.impl <= other.impl
|
||||||
|
|
||||||
def __floor__(self):
|
def __floor__(self):
|
||||||
return Rational(math.floor(self.impl))
|
return Rational(math.floor(self.impl))
|
||||||
|
|
||||||
|
def round(self, dps, mode):
|
||||||
|
"""Round to the specified number of decimal places, using the ROUND_* mode specified"""
|
||||||
|
factor = Fraction(10) ** dps
|
||||||
|
if mode == Rational.ROUND_DOWN:
|
||||||
|
return Rational(math.floor(self.impl * factor) / factor)
|
||||||
|
elif mode == Rational.ROUND_HALF_UP:
|
||||||
|
raise Exception('ROUND_HALF_UP is not implemented in Python Rational context')
|
||||||
|
elif mode == Rational.ROUND_HALF_EVEN:
|
||||||
|
return Rational(round(self.impl * factor) / factor)
|
||||||
|
elif mode == Rational.ROUND_UP:
|
||||||
|
return Rational(math.ceil(self.impl * factor) / factor)
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid rounding mode')
|
||||||
|
@ -56,3 +56,39 @@ test_fixed2_add_py, test_fixed2_add_js = maketst('Fixed', 2, '__add__', '356.57'
|
|||||||
test_fixed1_add_py, test_fixed1_add_js = maketst('Fixed', 1, '__add__', '356.6')
|
test_fixed1_add_py, test_fixed1_add_js = maketst('Fixed', 1, '__add__', '356.6')
|
||||||
test_fixed0_add_py, test_fixed0_add_js = maketst('Fixed', 0, '__add__', '356')
|
test_fixed0_add_py, test_fixed0_add_js = maketst('Fixed', 0, '__add__', '356')
|
||||||
test_rational_add_py, test_rational_add_js = maketst('Rational', 0, '__add__', '356.57')
|
test_rational_add_py, test_rational_add_js = maketst('Rational', 0, '__add__', '356.57')
|
||||||
|
|
||||||
|
def maketst_round(numbers, dps, num, dps_round, mode_round, result):
|
||||||
|
def t_py():
|
||||||
|
pyRCV2.numbers.set_numclass(getattr(pyRCV2.numbers, numbers))
|
||||||
|
pyRCV2.numbers.set_dps(dps)
|
||||||
|
|
||||||
|
num1 = Num(num)
|
||||||
|
assert num1.round(dps_round, getattr(num1, mode_round)) == Num(result)
|
||||||
|
|
||||||
|
def t_js():
|
||||||
|
ctx = py_mini_racer.MiniRacer()
|
||||||
|
|
||||||
|
# Imports
|
||||||
|
with open('html/vendor/BigInt_BigRat-a5f89e2.min.js', 'r') as f:
|
||||||
|
ctx.eval(f.read())
|
||||||
|
with open('html/vendor/big-6.0.0.min.js', 'r') as f:
|
||||||
|
ctx.eval(f.read())
|
||||||
|
with open('html/vendor/sjcl-1.0.8.min.js', 'r') as f:
|
||||||
|
ctx.eval(f.read())
|
||||||
|
with open('html/bundle.js', 'r') as f:
|
||||||
|
ctx.eval(f.read())
|
||||||
|
|
||||||
|
ctx.eval('py.pyRCV2.numbers.set_numclass(py.pyRCV2.numbers.{});'.format(numbers))
|
||||||
|
ctx.eval('py.pyRCV2.numbers.set_dps({});'.format(dps))
|
||||||
|
|
||||||
|
ctx.eval('num1 = py.pyRCV2.numbers.Num("{}"); void(0);'.format(num))
|
||||||
|
assert ctx.eval('num1.round({}, num1.{}).__eq__(py.pyRCV2.numbers.Num("{}"))'.format(dps_round, mode_round, result))
|
||||||
|
|
||||||
|
return t_py, t_js
|
||||||
|
|
||||||
|
test_fixed_round1_py, test_fixed_round1_js = maketst_round('Fixed', 5, '3141.59', 1, 'ROUND_DOWN', '3141.5')
|
||||||
|
test_fixed_round2_py, test_fixed_round2_js = maketst_round('Fixed', 5, '3141.59', 1, 'ROUND_UP', '3141.6')
|
||||||
|
test_native_round1_py, test_native_round1_js = maketst_round('Native', 0, '3141.59', 1, 'ROUND_DOWN', '3141.5')
|
||||||
|
test_native_round2_py, test_native_round2_js = maketst_round('Native', 0, '3141.59', 1, 'ROUND_UP', '3141.6')
|
||||||
|
test_rational_round1_py, test_rational_round1_js = maketst_round('Rational', 0, '3141.59', 1, 'ROUND_DOWN', '3141.5')
|
||||||
|
test_rational_round2_py, test_rational_round2_js = maketst_round('Rational', 0, '3141.59', 1, 'ROUND_UP', '3141.6')
|
||||||
|
Reference in New Issue
Block a user