| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <link rel="STYLESHEET" href="whatsnew24.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="whatsnew24.html" title='What's New in Python 2.4' /> |
| 8 | <link rel='contents' href='contents.html' title="Contents" /> |
| 9 | <link rel='last' href='about.html' title='About this document...' /> |
| 10 | <link rel='help' href='about.html' title='About this document...' /> |
| 11 | <link rel="next" href="node10.html" /> |
| 12 | <link rel="prev" href="node8.html" /> |
| 13 | <link rel="parent" href="whatsnew24.html" /> |
| 14 | <link rel="next" href="node10.html" /> |
| 15 | <meta name='aesop' content='information' /> |
| 16 | <title>8 PEP 327: Decimal Data Type</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="7 PEP 324: New" |
| 24 | href="node8.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="What's New in Python" |
| 27 | href="whatsnew24.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="9 PEP 328: Multi-line" |
| 30 | href="node10.html"><img src='../icons/next.png' |
| 31 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 32 | <td align="center" width="100%">What's New in Python 2.4</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'><img src='../icons/blank.png' |
| 37 | border='0' height='32' alt='' width='32' /></td> |
| 38 | <td class='online-navigation'><img src='../icons/blank.png' |
| 39 | border='0' height='32' alt='' width='32' /></td> |
| 40 | </tr></table> |
| 41 | <div class='online-navigation'> |
| 42 | <b class="navlabel">Previous:</b> |
| 43 | <a class="sectref" rel="prev" href="node8.html">7 PEP 324: New</A> |
| 44 | <b class="navlabel">Up:</b> |
| 45 | <a class="sectref" rel="parent" href="whatsnew24.html">What's New in Python</A> |
| 46 | <b class="navlabel">Next:</b> |
| 47 | <a class="sectref" rel="next" href="node10.html">9 PEP 328: Multi-line</A> |
| 48 | </div> |
| 49 | <hr /></div> |
| 50 | </DIV> |
| 51 | <!--End of Navigation Panel--> |
| 52 | <div class='online-navigation'> |
| 53 | <!--Table of Child-Links--> |
| 54 | <A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></a> |
| 55 | |
| 56 | <UL CLASS="ChildLinks"> |
| 57 | <LI><A href="node9.html#SECTION000910000000000000000">8.1 Why is Decimal needed?</a> |
| 58 | <LI><A href="node9.html#SECTION000920000000000000000">8.2 The <tt class="class">Decimal</tt> type</a> |
| 59 | <LI><A href="node9.html#SECTION000930000000000000000">8.3 The <tt class="class">Context</tt> type</a> |
| 60 | </ul> |
| 61 | <!--End of Table of Child-Links--> |
| 62 | </div> |
| 63 | <HR> |
| 64 | |
| 65 | <H1><A NAME="SECTION000900000000000000000"> |
| 66 | 8 PEP 327: Decimal Data Type</A> |
| 67 | </H1> |
| 68 | |
| 69 | <P> |
| 70 | Python has always supported floating-point (FP) numbers, based on the |
| 71 | underlying C <tt class="ctype">double</tt> type, as a data type. However, while most |
| 72 | programming languages provide a floating-point type, many people (even |
| 73 | programmers) are unaware that floating-point numbers don't represent |
| 74 | certain decimal fractions accurately. The new <tt class="class">Decimal</tt> type |
| 75 | can represent these fractions accurately, up to a user-specified |
| 76 | precision limit. |
| 77 | |
| 78 | <P> |
| 79 | |
| 80 | <H2><A NAME="SECTION000910000000000000000"> |
| 81 | 8.1 Why is Decimal needed?</A> |
| 82 | </H2> |
| 83 | |
| 84 | <P> |
| 85 | The limitations arise from the representation used for floating-point numbers. |
| 86 | FP numbers are made up of three components: |
| 87 | |
| 88 | <P> |
| 89 | |
| 90 | <UL> |
| 91 | <LI>The sign, which is positive or negative. |
| 92 | </LI> |
| 93 | <LI>The mantissa, which is a single-digit binary number |
| 94 | followed by a fractional part. For example, <code>1.01</code> in base-2 notation |
| 95 | is <code>1 + 0/2 + 1/4</code>, or 1.25 in decimal notation. |
| 96 | </LI> |
| 97 | <LI>The exponent, which tells where the decimal point is located in the number represented. |
| 98 | </LI> |
| 99 | </UL> |
| 100 | |
| 101 | <P> |
| 102 | For example, the number 1.25 has positive sign, a mantissa value of |
| 103 | 1.01 (in binary), and an exponent of 0 (the decimal point doesn't need |
| 104 | to be shifted). The number 5 has the same sign and mantissa, but the |
| 105 | exponent is 2 because the mantissa is multiplied by 4 (2 to the power |
| 106 | of the exponent 2); 1.25 * 4 equals 5. |
| 107 | |
| 108 | <P> |
| 109 | Modern systems usually provide floating-point support that conforms to |
| 110 | a standard called IEEE 754. C's <tt class="ctype">double</tt> type is usually |
| 111 | implemented as a 64-bit IEEE 754 number, which uses 52 bits of space |
| 112 | for the mantissa. This means that numbers can only be specified to 52 |
| 113 | bits of precision. If you're trying to represent numbers whose |
| 114 | expansion repeats endlessly, the expansion is cut off after 52 bits. |
| 115 | Unfortunately, most software needs to produce output in base 10, and |
| 116 | common fractions in base 10 are often repeating decimals in binary. |
| 117 | For example, 1.1 decimal is binary <code>1.0001100110011 ...</code>; .1 = |
| 118 | 1/16 + 1/32 + 1/256 plus an infinite number of additional terms. IEEE |
| 119 | 754 has to chop off that infinitely repeated decimal after 52 digits, |
| 120 | so the representation is slightly inaccurate. |
| 121 | |
| 122 | <P> |
| 123 | Sometimes you can see this inaccuracy when the number is printed: |
| 124 | <div class="verbatim"><pre> |
| 125 | >>> 1.1 |
| 126 | 1.1000000000000001 |
| 127 | </pre></div> |
| 128 | |
| 129 | <P> |
| 130 | The inaccuracy isn't always visible when you print the number because |
| 131 | the FP-to-decimal-string conversion is provided by the C library, and |
| 132 | most C libraries try to produce sensible output. Even if it's not |
| 133 | displayed, however, the inaccuracy is still there and subsequent |
| 134 | operations can magnify the error. |
| 135 | |
| 136 | <P> |
| 137 | For many applications this doesn't matter. If I'm plotting points and |
| 138 | displaying them on my monitor, the difference between 1.1 and |
| 139 | 1.1000000000000001 is too small to be visible. Reports often limit |
| 140 | output to a certain number of decimal places, and if you round the |
| 141 | number to two or three or even eight decimal places, the error is |
| 142 | never apparent. However, for applications where it does matter, |
| 143 | it's a lot of work to implement your own custom arithmetic routines. |
| 144 | |
| 145 | <P> |
| 146 | Hence, the <tt class="class">Decimal</tt> type was created. |
| 147 | |
| 148 | <P> |
| 149 | |
| 150 | <H2><A NAME="SECTION000920000000000000000"> |
| 151 | 8.2 The <tt class="class">Decimal</tt> type</A> |
| 152 | </H2> |
| 153 | |
| 154 | <P> |
| 155 | A new module, <tt class="module">decimal</tt>, was added to Python's standard |
| 156 | library. It contains two classes, <tt class="class">Decimal</tt> and |
| 157 | <tt class="class">Context</tt>. <tt class="class">Decimal</tt> instances represent numbers, and |
| 158 | <tt class="class">Context</tt> instances are used to wrap up various settings such as |
| 159 | the precision and default rounding mode. |
| 160 | |
| 161 | <P> |
| 162 | <tt class="class">Decimal</tt> instances are immutable, like regular Python integers |
| 163 | and FP numbers; once it's been created, you can't change the value an |
| 164 | instance represents. <tt class="class">Decimal</tt> instances can be created from |
| 165 | integers or strings: |
| 166 | |
| 167 | <P> |
| 168 | <div class="verbatim"><pre> |
| 169 | >>> import decimal |
| 170 | >>> decimal.Decimal(1972) |
| 171 | Decimal("1972") |
| 172 | >>> decimal.Decimal("1.1") |
| 173 | Decimal("1.1") |
| 174 | </pre></div> |
| 175 | |
| 176 | <P> |
| 177 | You can also provide tuples containing the sign, the mantissa represented |
| 178 | as a tuple of decimal digits, and the exponent: |
| 179 | |
| 180 | <P> |
| 181 | <div class="verbatim"><pre> |
| 182 | >>> decimal.Decimal((1, (1, 4, 7, 5), -2)) |
| 183 | Decimal("-14.75") |
| 184 | </pre></div> |
| 185 | |
| 186 | <P> |
| 187 | Cautionary note: the sign bit is a Boolean value, so 0 is positive and |
| 188 | 1 is negative. |
| 189 | |
| 190 | <P> |
| 191 | Converting from floating-point numbers poses a bit of a problem: |
| 192 | should the FP number representing 1.1 turn into the decimal number for |
| 193 | exactly 1.1, or for 1.1 plus whatever inaccuracies are introduced? |
| 194 | The decision was to dodge the issue and leave such a conversion out of |
| 195 | the API. Instead, you should convert the floating-point number into a |
| 196 | string using the desired precision and pass the string to the |
| 197 | <tt class="class">Decimal</tt> constructor: |
| 198 | |
| 199 | <P> |
| 200 | <div class="verbatim"><pre> |
| 201 | >>> f = 1.1 |
| 202 | >>> decimal.Decimal(str(f)) |
| 203 | Decimal("1.1") |
| 204 | >>> decimal.Decimal('%.12f' % f) |
| 205 | Decimal("1.100000000000") |
| 206 | </pre></div> |
| 207 | |
| 208 | <P> |
| 209 | Once you have <tt class="class">Decimal</tt> instances, you can perform the usual |
| 210 | mathematical operations on them. One limitation: exponentiation |
| 211 | requires an integer exponent: |
| 212 | |
| 213 | <P> |
| 214 | <div class="verbatim"><pre> |
| 215 | >>> a = decimal.Decimal('35.72') |
| 216 | >>> b = decimal.Decimal('1.73') |
| 217 | >>> a+b |
| 218 | Decimal("37.45") |
| 219 | >>> a-b |
| 220 | Decimal("33.99") |
| 221 | >>> a*b |
| 222 | Decimal("61.7956") |
| 223 | >>> a/b |
| 224 | Decimal("20.64739884393063583815028902") |
| 225 | >>> a ** 2 |
| 226 | Decimal("1275.9184") |
| 227 | >>> a**b |
| 228 | Traceback (most recent call last): |
| 229 | ... |
| 230 | decimal.InvalidOperation: x ** (non-integer) |
| 231 | </pre></div> |
| 232 | |
| 233 | <P> |
| 234 | You can combine <tt class="class">Decimal</tt> instances with integers, but not with |
| 235 | floating-point numbers: |
| 236 | |
| 237 | <P> |
| 238 | <div class="verbatim"><pre> |
| 239 | >>> a + 4 |
| 240 | Decimal("39.72") |
| 241 | >>> a + 4.5 |
| 242 | Traceback (most recent call last): |
| 243 | ... |
| 244 | TypeError: You can interact Decimal only with int, long or Decimal data types. |
| 245 | >>> |
| 246 | </pre></div> |
| 247 | |
| 248 | <P> |
| 249 | <tt class="class">Decimal</tt> numbers can be used with the <tt class="module">math</tt> and |
| 250 | <tt class="module">cmath</tt> modules, but note that they'll be immediately converted to |
| 251 | floating-point numbers before the operation is performed, resulting in |
| 252 | a possible loss of precision and accuracy. You'll also get back a |
| 253 | regular floating-point number and not a <tt class="class">Decimal</tt>. |
| 254 | |
| 255 | <P> |
| 256 | <div class="verbatim"><pre> |
| 257 | >>> import math, cmath |
| 258 | >>> d = decimal.Decimal('123456789012.345') |
| 259 | >>> math.sqrt(d) |
| 260 | 351364.18288201344 |
| 261 | >>> cmath.sqrt(-d) |
| 262 | 351364.18288201344j |
| 263 | </pre></div> |
| 264 | |
| 265 | <P> |
| 266 | <tt class="class">Decimal</tt> instances have a <tt class="method">sqrt()</tt> method that |
| 267 | returns a <tt class="class">Decimal</tt>, but if you need other things such as |
| 268 | trigonometric functions you'll have to implement them. |
| 269 | |
| 270 | <P> |
| 271 | <div class="verbatim"><pre> |
| 272 | >>> d.sqrt() |
| 273 | Decimal("351364.1828820134592177245001") |
| 274 | </pre></div> |
| 275 | |
| 276 | <P> |
| 277 | |
| 278 | <H2><A NAME="SECTION000930000000000000000"> |
| 279 | 8.3 The <tt class="class">Context</tt> type</A> |
| 280 | </H2> |
| 281 | |
| 282 | <P> |
| 283 | Instances of the <tt class="class">Context</tt> class encapsulate several settings for |
| 284 | decimal operations: |
| 285 | |
| 286 | <P> |
| 287 | |
| 288 | <UL> |
| 289 | <LI><tt class="member">prec</tt> is the precision, the number of decimal places. |
| 290 | </LI> |
| 291 | <LI><tt class="member">rounding</tt> specifies the rounding mode. The <tt class="module">decimal</tt> |
| 292 | module has constants for the various possibilities: |
| 293 | <tt class="constant">ROUND_DOWN</tt>, <tt class="constant">ROUND_CEILING</tt>, |
| 294 | <tt class="constant">ROUND_HALF_EVEN</tt>, and various others. |
| 295 | </LI> |
| 296 | <LI><tt class="member">traps</tt> is a dictionary specifying what happens on |
| 297 | encountering certain error conditions: either an exception is raised or |
| 298 | a value is returned. Some examples of error conditions are |
| 299 | division by zero, loss of precision, and overflow. |
| 300 | </LI> |
| 301 | </UL> |
| 302 | |
| 303 | <P> |
| 304 | There's a thread-local default context available by calling |
| 305 | <tt class="function">getcontext()</tt>; you can change the properties of this context |
| 306 | to alter the default precision, rounding, or trap handling. The |
| 307 | following example shows the effect of changing the precision of the default |
| 308 | context: |
| 309 | |
| 310 | <P> |
| 311 | <div class="verbatim"><pre> |
| 312 | >>> decimal.getcontext().prec |
| 313 | 28 |
| 314 | >>> decimal.Decimal(1) / decimal.Decimal(7) |
| 315 | Decimal("0.1428571428571428571428571429") |
| 316 | >>> decimal.getcontext().prec = 9 |
| 317 | >>> decimal.Decimal(1) / decimal.Decimal(7) |
| 318 | Decimal("0.142857143") |
| 319 | </pre></div> |
| 320 | |
| 321 | <P> |
| 322 | The default action for error conditions is selectable; the module can |
| 323 | either return a special value such as infinity or not-a-number, or |
| 324 | exceptions can be raised: |
| 325 | |
| 326 | <P> |
| 327 | <div class="verbatim"><pre> |
| 328 | >>> decimal.Decimal(1) / decimal.Decimal(0) |
| 329 | Traceback (most recent call last): |
| 330 | ... |
| 331 | decimal.DivisionByZero: x / 0 |
| 332 | >>> decimal.getcontext().traps[decimal.DivisionByZero] = False |
| 333 | >>> decimal.Decimal(1) / decimal.Decimal(0) |
| 334 | Decimal("Infinity") |
| 335 | >>> |
| 336 | </pre></div> |
| 337 | |
| 338 | <P> |
| 339 | The <tt class="class">Context</tt> instance also has various methods for formatting |
| 340 | numbers such as <tt class="method">to_eng_string()</tt> and <tt class="method">to_sci_string()</tt>. |
| 341 | |
| 342 | <P> |
| 343 | For more information, see the documentation for the <tt class="module">decimal</tt> |
| 344 | module, which includes a quick-start tutorial and a reference. |
| 345 | |
| 346 | <P> |
| 347 | <div class="seealso"> |
| 348 | <p class="heading">See Also:</p> |
| 349 | |
| 350 | <dl compact="compact" class="seerfc"> |
| 351 | <dt><a href="http://www.python.org/peps/pep-0327.html" |
| 352 | title="Decimal Data Type" |
| 353 | >PEP 327, <em>Decimal Data Type</em></a> |
| 354 | <dd>Written by Facundo Batista and implemented |
| 355 | by Facundo Batista, Eric Price, Raymond Hettinger, Aahz, and Tim Peters. |
| 356 | </dl> |
| 357 | |
| 358 | <P> |
| 359 | <dl compact="compact" class="seeurl"> |
| 360 | <dt><a href="http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html" |
| 361 | class="url">http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html</a></dt> |
| 362 | <dd>A more detailed overview of the IEEE-754 representation.</dd> |
| 363 | </dl> |
| 364 | |
| 365 | <P> |
| 366 | <dl compact="compact" class="seeurl"> |
| 367 | <dt><a href="http://www.lahey.com/float.htm" |
| 368 | class="url">http://www.lahey.com/float.htm</a></dt> |
| 369 | <dd>The article uses Fortran code to illustrate many of the problems |
| 370 | that floating-point inaccuracy can cause.</dd> |
| 371 | </dl> |
| 372 | |
| 373 | <P> |
| 374 | <dl compact="compact" class="seeurl"> |
| 375 | <dt><a href="http://www2.hursley.ibm.com/decimal/" |
| 376 | class="url">http://www2.hursley.ibm.com/decimal/</a></dt> |
| 377 | <dd>A description of a decimal-based representation. This representation |
| 378 | is being proposed as a standard, and underlies the new Python decimal |
| 379 | type. Much of this material was written by Mike Cowlishaw, designer of the |
| 380 | Rexx language.</dd> |
| 381 | </dl> |
| 382 | |
| 383 | <P> |
| 384 | </div> |
| 385 | |
| 386 | <P> |
| 387 | |
| 388 | <DIV CLASS="navigation"> |
| 389 | <div class='online-navigation'> |
| 390 | <p></p><hr /> |
| 391 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 392 | <tr> |
| 393 | <td class='online-navigation'><a rel="prev" title="7 PEP 324: New" |
| 394 | href="node8.html"><img src='../icons/previous.png' |
| 395 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 396 | <td class='online-navigation'><a rel="parent" title="What's New in Python" |
| 397 | href="whatsnew24.html"><img src='../icons/up.png' |
| 398 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 399 | <td class='online-navigation'><a rel="next" title="9 PEP 328: Multi-line" |
| 400 | href="node10.html"><img src='../icons/next.png' |
| 401 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 402 | <td align="center" width="100%">What's New in Python 2.4</td> |
| 403 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 404 | href="contents.html"><img src='../icons/contents.png' |
| 405 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 406 | <td class='online-navigation'><img src='../icons/blank.png' |
| 407 | border='0' height='32' alt='' width='32' /></td> |
| 408 | <td class='online-navigation'><img src='../icons/blank.png' |
| 409 | border='0' height='32' alt='' width='32' /></td> |
| 410 | </tr></table> |
| 411 | <div class='online-navigation'> |
| 412 | <b class="navlabel">Previous:</b> |
| 413 | <a class="sectref" rel="prev" href="node8.html">7 PEP 324: New</A> |
| 414 | <b class="navlabel">Up:</b> |
| 415 | <a class="sectref" rel="parent" href="whatsnew24.html">What's New in Python</A> |
| 416 | <b class="navlabel">Next:</b> |
| 417 | <a class="sectref" rel="next" href="node10.html">9 PEP 328: Multi-line</A> |
| 418 | </div> |
| 419 | </div> |
| 420 | <hr /> |
| 421 | <span class="release-info">Release 1.01.</span> |
| 422 | </DIV> |
| 423 | <!--End of Navigation Panel--> |
| 424 | <ADDRESS> |
| 425 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. |
| 426 | </ADDRESS> |
| 427 | </BODY> |
| 428 | </HTML> |