|
13 | 13 | # bug) and will be backported. At this point the spec is stabilizing |
14 | 14 | # and the updates are becoming fewer, smaller, and less significant. |
15 | 15 |
|
16 | | -""" |
17 | | -This is an implementation of decimal floating point arithmetic based on |
18 | | -the General Decimal Arithmetic Specification: |
19 | | -
|
20 | | - http://speleotrove.com/decimal/decarith.html |
21 | | -
|
22 | | -and IEEE standard 854-1987: |
23 | | -
|
24 | | - http://en.wikipedia.org/wiki/IEEE_854-1987 |
25 | | -
|
26 | | -Decimal floating point has finite precision with arbitrarily large bounds. |
27 | | -
|
28 | | -The purpose of this module is to support arithmetic using familiar |
29 | | -"schoolhouse" rules and to avoid some of the tricky representation |
30 | | -issues associated with binary floating point. The package is especially |
31 | | -useful for financial applications or for contexts where users have |
32 | | -expectations that are at odds with binary floating point (for instance, |
33 | | -in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead |
34 | | -of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected |
35 | | -Decimal('0.00')). |
36 | | -
|
37 | | -Here are some examples of using the decimal module: |
38 | | -
|
39 | | ->>> from decimal import * |
40 | | ->>> setcontext(ExtendedContext) |
41 | | ->>> Decimal(0) |
42 | | -Decimal('0') |
43 | | ->>> Decimal('1') |
44 | | -Decimal('1') |
45 | | ->>> Decimal('-.0123') |
46 | | -Decimal('-0.0123') |
47 | | ->>> Decimal(123456) |
48 | | -Decimal('123456') |
49 | | ->>> Decimal('123.45e12345678') |
50 | | -Decimal('1.2345E+12345680') |
51 | | ->>> Decimal('1.33') + Decimal('1.27') |
52 | | -Decimal('2.60') |
53 | | ->>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') |
54 | | -Decimal('-2.20') |
55 | | ->>> dig = Decimal(1) |
56 | | ->>> print(dig / Decimal(3)) |
57 | | -0.333333333 |
58 | | ->>> getcontext().prec = 18 |
59 | | ->>> print(dig / Decimal(3)) |
60 | | -0.333333333333333333 |
61 | | ->>> print(dig.sqrt()) |
62 | | -1 |
63 | | ->>> print(Decimal(3).sqrt()) |
64 | | -1.73205080756887729 |
65 | | ->>> print(Decimal(3) ** 123) |
66 | | -4.85192780976896427E+58 |
67 | | ->>> inf = Decimal(1) / Decimal(0) |
68 | | ->>> print(inf) |
69 | | -Infinity |
70 | | ->>> neginf = Decimal(-1) / Decimal(0) |
71 | | ->>> print(neginf) |
72 | | --Infinity |
73 | | ->>> print(neginf + inf) |
74 | | -NaN |
75 | | ->>> print(neginf * inf) |
76 | | --Infinity |
77 | | ->>> print(dig / 0) |
78 | | -Infinity |
79 | | ->>> getcontext().traps[DivisionByZero] = 1 |
80 | | ->>> print(dig / 0) |
81 | | -Traceback (most recent call last): |
82 | | - ... |
83 | | - ... |
84 | | - ... |
85 | | -decimal.DivisionByZero: x / 0 |
86 | | ->>> c = Context() |
87 | | ->>> c.traps[InvalidOperation] = 0 |
88 | | ->>> print(c.flags[InvalidOperation]) |
89 | | -0 |
90 | | ->>> c.divide(Decimal(0), Decimal(0)) |
91 | | -Decimal('NaN') |
92 | | ->>> c.traps[InvalidOperation] = 1 |
93 | | ->>> print(c.flags[InvalidOperation]) |
94 | | -1 |
95 | | ->>> c.flags[InvalidOperation] = 0 |
96 | | ->>> print(c.flags[InvalidOperation]) |
97 | | -0 |
98 | | ->>> print(c.divide(Decimal(0), Decimal(0))) |
99 | | -Traceback (most recent call last): |
100 | | - ... |
101 | | - ... |
102 | | - ... |
103 | | -decimal.InvalidOperation: 0 / 0 |
104 | | ->>> print(c.flags[InvalidOperation]) |
105 | | -1 |
106 | | ->>> c.flags[InvalidOperation] = 0 |
107 | | ->>> c.traps[InvalidOperation] = 0 |
108 | | ->>> print(c.divide(Decimal(0), Decimal(0))) |
109 | | -NaN |
110 | | ->>> print(c.flags[InvalidOperation]) |
111 | | -1 |
112 | | ->>> |
113 | | -""" |
| 16 | +"""Python decimal arithmetic module""" |
114 | 17 |
|
115 | 18 | __all__ = [ |
116 | 19 | # Two major classes |
@@ -2228,10 +2131,16 @@ def _power_exact(self, other, p): |
2228 | 2131 | else: |
2229 | 2132 | return None |
2230 | 2133 |
|
2231 | | - if xc >= 10**p: |
| 2134 | + # An exact power of 10 is representable, but can convert to a |
| 2135 | + # string of any length. But an exact power of 10 shouldn't be |
| 2136 | + # possible at this point. |
| 2137 | + assert xc > 1, self |
| 2138 | + assert xc % 10 != 0, self |
| 2139 | + strxc = str(xc) |
| 2140 | + if len(strxc) > p: |
2232 | 2141 | return None |
2233 | 2142 | xe = -e-xe |
2234 | | - return _dec_from_triple(0, str(xc), xe) |
| 2143 | + return _dec_from_triple(0, strxc, xe) |
2235 | 2144 |
|
2236 | 2145 | # now y is positive; find m and n such that y = m/n |
2237 | 2146 | if ye >= 0: |
@@ -2281,13 +2190,18 @@ def _power_exact(self, other, p): |
2281 | 2190 | return None |
2282 | 2191 | xc = xc**m |
2283 | 2192 | xe *= m |
2284 | | - if xc > 10**p: |
| 2193 | + # An exact power of 10 is representable, but can convert to a string |
| 2194 | + # of any length. But an exact power of 10 shouldn't be possible at |
| 2195 | + # this point. |
| 2196 | + assert xc > 1, self |
| 2197 | + assert xc % 10 != 0, self |
| 2198 | + str_xc = str(xc) |
| 2199 | + if len(str_xc) > p: |
2285 | 2200 | return None |
2286 | 2201 |
|
2287 | 2202 | # by this point the result *is* exactly representable |
2288 | 2203 | # adjust the exponent to get as close as possible to the ideal |
2289 | 2204 | # exponent, if necessary |
2290 | | - str_xc = str(xc) |
2291 | 2205 | if other._isinteger() and other._sign == 0: |
2292 | 2206 | ideal_exponent = self._exp*int(other) |
2293 | 2207 | zeros = min(xe-ideal_exponent, p-len(str_xc)) |
|
0 commit comments