Left: | ||
Right: |
OLD | NEW |
---|---|
1 | 1 |
2 /* Complex object implementation */ | 2 /* Complex object implementation */ |
3 | 3 |
4 /* Borrows heavily from floatobject.c */ | 4 /* Borrows heavily from floatobject.c */ |
5 | 5 |
6 /* Submitted by Jim Hugunin */ | 6 /* Submitted by Jim Hugunin */ |
7 | 7 |
8 #include "Python.h" | 8 #include "Python.h" |
9 #include "structmember.h" | 9 #include "structmember.h" |
10 | 10 |
11 #ifdef HAVE_IEEEFP_H | 11 #ifdef HAVE_IEEEFP_H |
12 #include <ieeefp.h> | 12 #include <ieeefp.h> |
13 #endif | 13 #endif |
14 | 14 |
15 #ifndef WITHOUT_COMPLEX | 15 #ifndef WITHOUT_COMPLEX |
16 | 16 |
17 /* Precisions used by repr() and str(), respectively. | |
18 | |
19 The repr() precision (17 significant decimal digits) is the minimal number | |
20 that is guaranteed to have enough precision so that if the number is read | |
21 back in the exact same binary value is recreated. This is true for IEEE | |
22 floating point by design, and also happens to work for all other modern | |
23 hardware. | |
24 | |
25 The str() precision is chosen so that in most cases, the rounding noise | |
26 created by various operations is suppressed, while giving plenty of | |
27 precision for practical use. | |
28 */ | |
29 | |
30 #define PREC_REPR 17 | |
31 #define PREC_STR 12 | |
32 | |
33 /* elementary operations on complex numbers */ | 17 /* elementary operations on complex numbers */ |
34 | 18 |
35 static Py_complex c_1 = {1., 0.}; | 19 static Py_complex c_1 = {1., 0.}; |
36 | 20 |
37 Py_complex | 21 Py_complex |
38 c_sum(Py_complex a, Py_complex b) | 22 c_sum(Py_complex a, Py_complex b) |
39 { | 23 { |
40 Py_complex r; | 24 Py_complex r; |
41 r.real = a.real + b.real; | 25 r.real = a.real + b.real; |
42 r.imag = a.imag + b.imag; | 26 r.imag = a.imag + b.imag; |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 } | 322 } |
339 } | 323 } |
340 | 324 |
341 static void | 325 static void |
342 complex_dealloc(PyObject *op) | 326 complex_dealloc(PyObject *op) |
343 { | 327 { |
344 op->ob_type->tp_free(op); | 328 op->ob_type->tp_free(op); |
345 } | 329 } |
346 | 330 |
347 | 331 |
348 static void | 332 static PyObject * |
349 complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision) | 333 complex_format(PyComplexObject *v, char format_code) |
350 { | 334 { |
351 » char format[32]; | 335 PyObject *result = NULL; |
352 » if (v->cval.real == 0.) { | 336 Py_ssize_t len; |
353 » » if (!Py_IS_FINITE(v->cval.imag)) { | 337 char *buf; |
354 » » » if (Py_IS_NAN(v->cval.imag)) | 338 |
355 » » » » strncpy(buf, "nan*j", 6); | 339 /* If these are non-NULL, they'll need to be freed. */ |
356 » » » else if (copysign(1, v->cval.imag) == 1) | 340 char *pre = NULL; |
357 » » » » strncpy(buf, "inf*j", 6); | 341 char *pim = NULL; |
358 » » » else | 342 |
359 » » » » strncpy(buf, "-inf*j", 7); | 343 /* These do not need to be freed. They're either aliases for pim |
360 » » } | 344 and pre, or pointers to constants. */ |
361 » » else { | 345 char *re = NULL; |
362 » » » PyOS_snprintf(format, sizeof(format), "%%.%ig", precisio n); | 346 char *im = NULL; |
363 » » » PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag) ; | 347 char *lead = ""; |
364 » » » strncat(buf, "j", 1); | 348 char *tail = ""; |
365 » » } | 349 |
366 » } else { | 350 |
367 » » char re[64], im[64]; | 351 if (v->cval.real == 0.) { |
368 » » /* Format imaginary part with sign, real part without */ | 352 re = ""; |
369 » » if (!Py_IS_FINITE(v->cval.real)) { | 353 if (!Py_IS_FINITE(v->cval.imag)) { |
370 » » » if (Py_IS_NAN(v->cval.real)) | 354 if (Py_IS_NAN(v->cval.imag)) |
371 » » » » strncpy(re, "nan", 4); | 355 im = "nan*"; |
372 » » » /* else if (copysign(1, v->cval.real) == 1) */ | 356 else if (copysign(1, v->cval.imag) == 1) |
373 » » » else if (v->cval.real > 0) | 357 im = "inf*"; |
374 » » » » strncpy(re, "inf", 4); | 358 else |
375 » » » else | 359 im = "-inf*"; |
376 » » » » strncpy(re, "-inf", 5); | 360 } |
377 » » } | 361 else { |
378 » » else { | 362 pim = PyOS_double_to_string(v->cval.imag, format_code, 0, 0); |
379 » » » PyOS_snprintf(format, sizeof(format), "%%.%ig", precisio n); | 363 if (!pim) { |
380 » » » PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real) ; | 364 PyErr_NoMemory(); |
381 » » } | 365 goto done; |
382 » » if (!Py_IS_FINITE(v->cval.imag)) { | 366 } |
383 » » » if (Py_IS_NAN(v->cval.imag)) | 367 im = pim; |
384 » » » » strncpy(im, "+nan*", 6); | 368 } |
385 » » » /* else if (copysign(1, v->cval.imag) == 1) */ | 369 } else { |
386 » » » else if (v->cval.imag > 0) | 370 /* Format imaginary part with sign, real part without */ |
387 » » » » strncpy(im, "+inf*", 6); | 371 if (!Py_IS_FINITE(v->cval.real)) { |
388 » » » else | 372 if (Py_IS_NAN(v->cval.real)) |
389 » » » » strncpy(im, "-inf*", 6); | 373 re = "nan"; |
390 » » } | 374 /* else if (copysign(1, v->cval.real) == 1) */ |
391 » » else { | 375 else if (v->cval.real > 0) |
392 » » » PyOS_snprintf(format, sizeof(format), "%%+.%ig", precisi on); | 376 re = "inf"; |
393 » » » PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag) ; | 377 else |
394 » » } | 378 re = "-inf"; |
395 » » PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im); | 379 } |
396 » } | 380 else { |
381 pre = PyOS_double_to_string(v->cval.real, format_code, 0, 0); | |
382 if (!pre) { | |
383 PyErr_NoMemory(); | |
384 goto done; | |
385 } | |
386 re = pre; | |
387 } | |
388 | |
389 if (!Py_IS_FINITE(v->cval.imag)) { | |
390 if (Py_IS_NAN(v->cval.imag)) | |
391 im = "+nan*"; | |
392 /* else if (copysign(1, v->cval.imag) == 1) */ | |
393 else if (v->cval.imag > 0) | |
394 im = "+inf*"; | |
395 else | |
396 im = "-inf*"; | |
397 } | |
398 else { | |
399 pim = PyOS_double_to_string(v->cval.imag, format_code, | |
400 0, Py_DTSF_SIGN); | |
401 if (!pim) { | |
402 PyErr_NoMemory(); | |
403 goto done; | |
404 } | |
405 im = pim; | |
406 } | |
407 lead = "("; | |
408 tail = ")"; | |
409 } | |
410 /* Alloc the final buffer. Add one for the "j" in the format string, and | |
411 one for the trailing zero. */ | |
412 len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2; | |
413 buf = PyMem_Malloc(len); | |
Nick Coghlan
2009/04/09 10:52:04
Where does buf get freed?
ericvsmith
2009/04/09 11:44:20
Good catch. I'll fix that.
| |
414 if (!buf) { | |
415 PyErr_NoMemory(); | |
416 goto done; | |
417 } | |
418 PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail); | |
419 result = PyUnicode_FromString(buf); | |
420 done: | |
421 PyMem_Free(pim); | |
422 PyMem_Free(pre); | |
423 | |
424 return result; | |
397 } | 425 } |
398 | 426 |
399 static PyObject * | 427 static PyObject * |
400 complex_repr(PyComplexObject *v) | 428 complex_repr(PyComplexObject *v) |
401 { | 429 { |
402 » char buf[100]; | 430 return complex_format(v, 'r'); |
403 » complex_to_buf(buf, sizeof(buf), v, PREC_REPR); | |
404 » return PyUnicode_FromString(buf); | |
405 } | 431 } |
406 | 432 |
407 static PyObject * | 433 static PyObject * |
408 complex_str(PyComplexObject *v) | 434 complex_str(PyComplexObject *v) |
409 { | 435 { |
410 » char buf[100]; | 436 return complex_format(v, 's'); |
411 » complex_to_buf(buf, sizeof(buf), v, PREC_STR); | |
412 » return PyUnicode_FromString(buf); | |
413 } | 437 } |
414 | 438 |
415 static long | 439 static long |
416 complex_hash(PyComplexObject *v) | 440 complex_hash(PyComplexObject *v) |
417 { | 441 { |
418 long hashreal, hashimag, combined; | 442 long hashreal, hashimag, combined; |
419 hashreal = _Py_HashDouble(v->cval.real); | 443 hashreal = _Py_HashDouble(v->cval.real); |
420 if (hashreal == -1) | 444 if (hashreal == -1) |
421 return -1; | 445 return -1; |
422 hashimag = _Py_HashDouble(v->cval.imag); | 446 hashimag = _Py_HashDouble(v->cval.imag); |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1114 0, /* tp_descr_get */ | 1138 0, /* tp_descr_get */ |
1115 0, /* tp_descr_set */ | 1139 0, /* tp_descr_set */ |
1116 0, /* tp_dictoffset */ | 1140 0, /* tp_dictoffset */ |
1117 0, /* tp_init */ | 1141 0, /* tp_init */ |
1118 PyType_GenericAlloc, /* tp_alloc */ | 1142 PyType_GenericAlloc, /* tp_alloc */ |
1119 complex_new, /* tp_new */ | 1143 complex_new, /* tp_new */ |
1120 PyObject_Del, /* tp_free */ | 1144 PyObject_Del, /* tp_free */ |
1121 }; | 1145 }; |
1122 | 1146 |
1123 #endif | 1147 #endif |
OLD | NEW |