Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <link rel="STYLESHEET" href="lib.css" type='text/css' /> | |
5 | <link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" /> | |
6 | <link rel='start' href='../index.html' title='Python Documentation Index' /> | |
7 | <link rel="first" href="lib.html" title='Python Library Reference' /> | |
8 | <link rel='contents' href='contents.html' title="Contents" /> | |
9 | <link rel='index' href='genindex.html' title='Index' /> | |
10 | <link rel='last' href='about.html' title='About this document...' /> | |
11 | <link rel='help' href='about.html' title='About this document...' /> | |
12 | <link rel="prev" href="decimal-recipes.html" /> | |
13 | <link rel="parent" href="module-decimal.html" /> | |
14 | <link rel="next" href="module-math.html" /> | |
15 | <meta name='aesop' content='information' /> | |
16 | <title>5.6.8 Decimal FAQ </title> | |
17 | </head> | |
18 | <body> | |
19 | <DIV CLASS="navigation"> | |
20 | <div id='top-navigation-panel' xml:id='top-navigation-panel'> | |
21 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> | |
22 | <tr> | |
23 | <td class='online-navigation'><a rel="prev" title="5.6.7 Recipes" | |
24 | href="decimal-recipes.html"><img src='../icons/previous.png' | |
25 | border='0' height='32' alt='Previous Page' width='32' /></A></td> | |
26 | <td class='online-navigation'><a rel="parent" title="5.6 decimal " | |
27 | href="module-decimal.html"><img src='../icons/up.png' | |
28 | border='0' height='32' alt='Up One Level' width='32' /></A></td> | |
29 | <td class='online-navigation'><a rel="next" title="5.7 math " | |
30 | href="module-math.html"><img src='../icons/next.png' | |
31 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
32 | <td align="center" width="100%">Python Library Reference</td> | |
33 | <td class='online-navigation'><a rel="contents" title="Table of Contents" | |
34 | href="contents.html"><img src='../icons/contents.png' | |
35 | border='0' height='32' alt='Contents' width='32' /></A></td> | |
36 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' | |
37 | border='0' height='32' alt='Module Index' width='32' /></a></td> | |
38 | <td class='online-navigation'><a rel="index" title="Index" | |
39 | href="genindex.html"><img src='../icons/index.png' | |
40 | border='0' height='32' alt='Index' width='32' /></A></td> | |
41 | </tr></table> | |
42 | <div class='online-navigation'> | |
43 | <b class="navlabel">Previous:</b> | |
44 | <a class="sectref" rel="prev" href="decimal-recipes.html">5.6.7 Recipes</A> | |
45 | <b class="navlabel">Up:</b> | |
46 | <a class="sectref" rel="parent" href="module-decimal.html">5.6 decimal </A> | |
47 | <b class="navlabel">Next:</b> | |
48 | <a class="sectref" rel="next" href="module-math.html">5.7 math </A> | |
49 | </div> | |
50 | <hr /></div> | |
51 | </DIV> | |
52 | <!--End of Navigation Panel--> | |
53 | ||
54 | <H2><A NAME="SECTION007680000000000000000"></A><A NAME="decimal-faq"></A> | |
55 | <BR> | |
56 | 5.6.8 Decimal FAQ | |
57 | </H2> | |
58 | ||
59 | <P> | |
60 | Q. It is cumbersome to type <code>decimal.Decimal('1234.5')</code>. Is there a way | |
61 | to minimize typing when using the interactive interpreter? | |
62 | ||
63 | <P> | |
64 | A. Some users abbreviate the constructor to just a single letter: | |
65 | ||
66 | <P> | |
67 | <div class="verbatim"><pre> | |
68 | >>> D = decimal.Decimal | |
69 | >>> D('1.23') + D('3.45') | |
70 | Decimal("4.68") | |
71 | </pre></div> | |
72 | ||
73 | <P> | |
74 | Q. In a fixed-point application with two decimal places, some inputs | |
75 | have many places and need to be rounded. Others are not supposed to have | |
76 | excess digits and need to be validated. What methods should be used? | |
77 | ||
78 | <P> | |
79 | A. The <tt class="method">quantize()</tt> method rounds to a fixed number of decimal places. | |
80 | If the <tt class="constant">Inexact</tt> trap is set, it is also useful for validation: | |
81 | ||
82 | <P> | |
83 | <div class="verbatim"><pre> | |
84 | >>> TWOPLACES = Decimal(10) ** -2 # same as Decimal('0.01') | |
85 | ||
86 | >>> # Round to two places | |
87 | >>> Decimal("3.214").quantize(TWOPLACES) | |
88 | Decimal("3.21") | |
89 | ||
90 | >>> # Validate that a number does not exceed two places | |
91 | >>> Decimal("3.21").quantize(TWOPLACES, context=Context(traps=[Inexact])) | |
92 | Decimal("3.21") | |
93 | ||
94 | >>> Decimal("3.214").quantize(TWOPLACES, context=Context(traps=[Inexact])) | |
95 | Traceback (most recent call last): | |
96 | ... | |
97 | Inexact: Changed in rounding | |
98 | </pre></div> | |
99 | ||
100 | <P> | |
101 | Q. Once I have valid two place inputs, how do I maintain that invariant | |
102 | throughout an application? | |
103 | ||
104 | <P> | |
105 | A. Some operations like addition and subtraction automatically preserve fixed | |
106 | point. Others, like multiplication and division, change the number of decimal | |
107 | places and need to be followed-up with a <tt class="method">quantize()</tt> step. | |
108 | ||
109 | <P> | |
110 | Q. There are many ways to express the same value. The numbers | |
111 | <tt class="constant">200</tt>, <tt class="constant">200.000</tt>, <tt class="constant">2E2</tt>, and <tt class="constant">.02E+4</tt> all | |
112 | have the same value at various precisions. Is there a way to transform them to | |
113 | a single recognizable canonical value? | |
114 | ||
115 | <P> | |
116 | A. The <tt class="method">normalize()</tt> method maps all equivalent values to a single | |
117 | representive: | |
118 | ||
119 | <P> | |
120 | <div class="verbatim"><pre> | |
121 | >>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split()) | |
122 | >>> [v.normalize() for v in values] | |
123 | [Decimal("2E+2"), Decimal("2E+2"), Decimal("2E+2"), Decimal("2E+2")] | |
124 | </pre></div> | |
125 | ||
126 | <P> | |
127 | Q. Some decimal values always print with exponential notation. Is there | |
128 | a way to get a non-exponential representation? | |
129 | ||
130 | <P> | |
131 | A. For some values, exponential notation is the only way to express | |
132 | the number of significant places in the coefficient. For example, | |
133 | expressing <tt class="constant">5.0E+3</tt> as <tt class="constant">5000</tt> keeps the value | |
134 | constant but cannot show the original's two-place significance. | |
135 | ||
136 | <P> | |
137 | Q. Is there a way to convert a regular float to a <tt class="class">Decimal</tt>? | |
138 | ||
139 | <P> | |
140 | A. Yes, all binary floating point numbers can be exactly expressed as a | |
141 | Decimal. An exact conversion may take more precision than intuition would | |
142 | suggest, so trapping <tt class="constant">Inexact</tt> will signal a need for more precision: | |
143 | ||
144 | <P> | |
145 | <div class="verbatim"><pre> | |
146 | def floatToDecimal(f): | |
147 | "Convert a floating point number to a Decimal with no loss of information" | |
148 | # Transform (exactly) a float to a mantissa (0.5 <= abs(m) < 1.0) and an | |
149 | # exponent. Double the mantissa until it is an integer. Use the integer | |
150 | # mantissa and exponent to compute an equivalent Decimal. If this cannot | |
151 | # be done exactly, then retry with more precision. | |
152 | ||
153 | mantissa, exponent = math.frexp(f) | |
154 | while mantissa != int(mantissa): | |
155 | mantissa *= 2.0 | |
156 | exponent -= 1 | |
157 | mantissa = int(mantissa) | |
158 | ||
159 | oldcontext = getcontext() | |
160 | setcontext(Context(traps=[Inexact])) | |
161 | try: | |
162 | while True: | |
163 | try: | |
164 | return mantissa * Decimal(2) ** exponent | |
165 | except Inexact: | |
166 | getcontext().prec += 1 | |
167 | finally: | |
168 | setcontext(oldcontext) | |
169 | </pre></div> | |
170 | ||
171 | <P> | |
172 | Q. Why isn't the <tt class="function">floatToDecimal()</tt> routine included in the module? | |
173 | ||
174 | <P> | |
175 | A. There is some question about whether it is advisable to mix binary and | |
176 | decimal floating point. Also, its use requires some care to avoid the | |
177 | representation issues associated with binary floating point: | |
178 | ||
179 | <P> | |
180 | <div class="verbatim"><pre> | |
181 | >>> floatToDecimal(1.1) | |
182 | Decimal("1.100000000000000088817841970012523233890533447265625") | |
183 | </pre></div> | |
184 | ||
185 | <P> | |
186 | Q. Within a complex calculation, how can I make sure that I haven't gotten a | |
187 | spurious result because of insufficient precision or rounding anomalies. | |
188 | ||
189 | <P> | |
190 | A. The decimal module makes it easy to test results. A best practice is to | |
191 | re-run calculations using greater precision and with various rounding modes. | |
192 | Widely differing results indicate insufficient precision, rounding mode | |
193 | issues, ill-conditioned inputs, or a numerically unstable algorithm. | |
194 | ||
195 | <P> | |
196 | Q. I noticed that context precision is applied to the results of operations | |
197 | but not to the inputs. Is there anything to watch out for when mixing | |
198 | values of different precisions? | |
199 | ||
200 | <P> | |
201 | A. Yes. The principle is that all values are considered to be exact and so | |
202 | is the arithmetic on those values. Only the results are rounded. The | |
203 | advantage for inputs is that ``what you type is what you get''. A | |
204 | disadvantage is that the results can look odd if you forget that the inputs | |
205 | haven't been rounded: | |
206 | ||
207 | <P> | |
208 | <div class="verbatim"><pre> | |
209 | >>> getcontext().prec = 3 | |
210 | >>> Decimal('3.104') + D('2.104') | |
211 | Decimal("5.21") | |
212 | >>> Decimal('3.104') + D('0.000') + D('2.104') | |
213 | Decimal("5.20") | |
214 | </pre></div> | |
215 | ||
216 | <P> | |
217 | The solution is either to increase precision or to force rounding of inputs | |
218 | using the unary plus operation: | |
219 | ||
220 | <P> | |
221 | <div class="verbatim"><pre> | |
222 | >>> getcontext().prec = 3 | |
223 | >>> +Decimal('1.23456789') # unary plus triggers rounding | |
224 | Decimal("1.23") | |
225 | </pre></div> | |
226 | ||
227 | <P> | |
228 | Alternatively, inputs can be rounded upon creation using the | |
229 | <tt class="method">Context.create_decimal()</tt> method: | |
230 | ||
231 | <P> | |
232 | <div class="verbatim"><pre> | |
233 | >>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678') | |
234 | Decimal("1.2345") | |
235 | </pre></div> | |
236 | ||
237 | <DIV CLASS="navigation"> | |
238 | <div class='online-navigation'> | |
239 | <p></p><hr /> | |
240 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> | |
241 | <tr> | |
242 | <td class='online-navigation'><a rel="prev" title="5.6.7 Recipes" | |
243 | href="decimal-recipes.html"><img src='../icons/previous.png' | |
244 | border='0' height='32' alt='Previous Page' width='32' /></A></td> | |
245 | <td class='online-navigation'><a rel="parent" title="5.6 decimal " | |
246 | href="module-decimal.html"><img src='../icons/up.png' | |
247 | border='0' height='32' alt='Up One Level' width='32' /></A></td> | |
248 | <td class='online-navigation'><a rel="next" title="5.7 math " | |
249 | href="module-math.html"><img src='../icons/next.png' | |
250 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
251 | <td align="center" width="100%">Python Library Reference</td> | |
252 | <td class='online-navigation'><a rel="contents" title="Table of Contents" | |
253 | href="contents.html"><img src='../icons/contents.png' | |
254 | border='0' height='32' alt='Contents' width='32' /></A></td> | |
255 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' | |
256 | border='0' height='32' alt='Module Index' width='32' /></a></td> | |
257 | <td class='online-navigation'><a rel="index" title="Index" | |
258 | href="genindex.html"><img src='../icons/index.png' | |
259 | border='0' height='32' alt='Index' width='32' /></A></td> | |
260 | </tr></table> | |
261 | <div class='online-navigation'> | |
262 | <b class="navlabel">Previous:</b> | |
263 | <a class="sectref" rel="prev" href="decimal-recipes.html">5.6.7 Recipes</A> | |
264 | <b class="navlabel">Up:</b> | |
265 | <a class="sectref" rel="parent" href="module-decimal.html">5.6 decimal </A> | |
266 | <b class="navlabel">Next:</b> | |
267 | <a class="sectref" rel="next" href="module-math.html">5.7 math </A> | |
268 | </div> | |
269 | </div> | |
270 | <hr /> | |
271 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> | |
272 | </DIV> | |
273 | <!--End of Navigation Panel--> | |
274 | <ADDRESS> | |
275 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. | |
276 | </ADDRESS> | |
277 | </BODY> | |
278 | </HTML> |