|
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