# [Python-checkins] r55890 - python/branches/decimal-branch/Lib/decimal.py

facundo.batista python-checkins at python.org
Mon Jun 11 15:06:19 CEST 2007

Author: facundo.batista
Date: Mon Jun 11 15:06:14 2007
New Revision: 55890

Modified:
python/branches/decimal-branch/Lib/decimal.py
Log:

Coded the functions scaleb, shift and rotate. All tests pass ok.

Modified: python/branches/decimal-branch/Lib/decimal.py
==============================================================================
--- python/branches/decimal-branch/Lib/decimal.py	(original)
+++ python/branches/decimal-branch/Lib/decimal.py	Mon Jun 11 15:06:14 2007
@@ -2570,12 +2570,106 @@

def rotate(self, other, context=None):
"""Returns a rotated copy of self, value-of-other times."""
+        if context is None:
+            context = getcontext()
+
+        ans = self._check_nans(other, context)
+        if ans:
+            return ans
+
+        if other._exp != 0:
+            return context._raise_error(InvalidOperation)
+        if not (-context.prec <= int(other) <= context.prec):
+            return context._raise_error(InvalidOperation)
+
+        if self._isinfinity():
+            return self
+
+        # get values, pad if necessary
+        torot = int(other)
+        rotdig = self._int
+        topad = context.prec - len(rotdig)
+            rotdig = ((0,)*topad) + rotdig
+
+        # let's rotate!
+        rotated = rotdig[torot:] + rotdig[:torot]
+
+        # clean starting zeroes
+        for i,d in enumerate(rotated):
+            if d != 0:
+                break
+        rotated = rotated[i:]
+
+        return Decimal((self._sign, rotated, self._exp))
+

def scaleb (self, other, context=None):
"""Returns self operand after adding the second value to its exp."""
+        if context is None:
+            context = getcontext()
+
+        ans = self._check_nans(other, context)
+        if ans:
+            return ans
+
+        if other._exp != 0:
+            return context._raise_error(InvalidOperation)
+        liminf = -2 * (context.Emax + context.prec)
+        limsup =  2 * (context.Emax + context.prec)
+        if not (liminf <= int(other) <= limsup):
+            return context._raise_error(InvalidOperation)
+
+        if self._isinfinity():
+            return self
+
+        d = Decimal((self._sign, self._int, self._exp + int(other)))
+        d = d._fixexponents(context)
+        return d

def shift(self, other, context=None):
"""Returns a shifted copy of self, value-of-other times."""
+        if context is None:
+            context = getcontext()
+
+        ans = self._check_nans(other, context)
+        if ans:
+            return ans
+
+        if other._exp != 0:
+            return context._raise_error(InvalidOperation)
+        if not (-context.prec <= int(other) <= context.prec):
+            return context._raise_error(InvalidOperation)
+
+        if self._isinfinity():
+            return self
+
+        # get values, pad if necessary
+        torot = int(other)
+        if not torot:
+            return self
+        rotdig = self._int
+        topad = context.prec - len(rotdig)
+            rotdig = ((0,)*topad) + rotdig
+
+        # let's shift!
+        if torot < 0:
+            rotated = rotdig[:torot]
+        else:
+            rotated = (rotdig + ((0,) * torot))
+            rotated = rotated[-context.prec:]
+
+        # clean starting zeroes
+        if rotated:
+            for i,d in enumerate(rotated):
+                if d != 0:
+                    break
+            rotated = rotated[i:]
+        else:
+            rotated = (0,)
+
+        return Decimal((self._sign, rotated, self._exp))

# Support for pickling, copy, and deepcopy