First of all I would like to mention that this question is not a duplicate of:
Python Rounding Inconsistently
I know about IEEE 754 and I know that:
The simple "always round 0.5 up" technique results in a slight bias toward the higher number. With large numbers of calculations, this can be significant. The Python 3.0 approach eliminates this issue.
I agree that ROUND_HALF_UP is inferior method to the one implemented by default in Python. Nevertheless there are people who do not know that and one needs to use that method if the specs require that. Easy way to make this work is:
def round_my(num, precission):
exp = 2*10**(-precission)
temp = num * exp
if temp%2 < 1:
return int(temp - temp%2)/exp
else:
return int(temp - temp%2 + 2)/exp
But my consideration is that this is not Pythonic... According to the docs I should use something like:
def round_my(num, pricission):
N_PLACES = Decimal(10) ** pricission # same as Decimal('0.01')
# Round to n places
Decimal(num).quantize(N_PLACES)
The problem is that this would not pass all test cases:
class myRound(unittest.TestCase):
def test_1(self):
self.assertEqual(piotrSQL.round_my(1.53, -1), 1.5)
self.assertEqual(piotrSQL.round_my(1.55, -1), 1.6)
self.assertEqual(piotrSQL.round_my(1.63, -1), 1.6)
self.assertEqual(piotrSQL.round_my(1.65, -1), 1.7)
self.assertEqual(piotrSQL.round_my(1.53, -2), 1.53)
self.assertEqual(piotrSQL.round_my(1.53, -3), 1.53)
self.assertEqual(piotrSQL.round_my(1.53, 0), 2)
self.assertEqual(piotrSQL.round_my(1.53, 1), 0)
self.assertEqual(piotrSQL.round_my(15.3, 1), 20)
self.assertEqual(piotrSQL.round_my(157.3, 2), 200)
Because of the nature of conversion between float and decimal and because quantize does not seem to be working for exponents like 10 or 100. Is there a Pythonic way to do this?
And I know that I could just add infinitesimally small number and round(num+10**(precission-20),-pricission)
would work but this is so wrong that "the puppies would die"...