# HG changeset patch
# User Jean-Pierre Flori <jean-pierre.flor@ssi.gouv.fr>
# Date 1334152948 -7200
# Node ID 526c2d3fd326668b7462015f58fc0f80718ed51c
# Parent 93441f72762981dddd4991ba23ff46cd9a98aafa
#715: the C % operator can return negative results.
diff --git a/sage/structure/coerce_dict.pyx b/sage/structure/coerce_dict.pyx
a
|
b
|
|
99 | 99 | # We remove that unique triple from self.D |
100 | 100 | cdef Py_ssize_t k1,k2,k3 |
101 | 101 | k1,k2,k3 = r.key |
102 | | cdef int h = (k1 + 13*k2 ^ 503*k3) % PyList_GET_SIZE(self.D.buckets) |
103 | | cdef list bucket = <object>PyList_GET_ITEM(self.D.buckets,h) |
| 102 | cdef Py_ssize_t h = (k1 + 13*k2 ^ 503*k3) |
| 103 | # Beware that the C "%" operator returns negative values if the input |
| 104 | # is negative, which is not the case of the Python "%" operator |
| 105 | if h < 0: h = -h |
| 106 | h = h % PyList_GET_SIZE(self.D.buckets) |
| 107 | cdef list bucket = <object>PyList_GET_ITEM(self.D.buckets, h) |
104 | 108 | cdef int i |
105 | 109 | for i from 0 <= i < PyList_GET_SIZE(bucket) by 4: |
106 | | if <Py_ssize_t><object>PyList_GET_ITEM(bucket,i)==k1 and \ |
107 | | <Py_ssize_t><object>PyList_GET_ITEM(bucket,i+1)==k2 and \ |
108 | | <Py_ssize_t><object>PyList_GET_ITEM(bucket,i+2)==k3: |
| 110 | if <Py_ssize_t><object>PyList_GET_ITEM(bucket, i)==k1 and \ |
| 111 | <Py_ssize_t><object>PyList_GET_ITEM(bucket, i+1)==k2 and \ |
| 112 | <Py_ssize_t><object>PyList_GET_ITEM(bucket, i+2)==k3: |
109 | 113 | del bucket[i:i+4] |
110 | 114 | self.D._size -= 1 |
111 | 115 | break |
… |
… |
|
352 | 356 | except (TypeError,ValueError): |
353 | 357 | raise KeyError, k |
354 | 358 | return self.get(k1, k2, k3) |
355 | | |
| 359 | |
356 | 360 | cdef get(self, object k1, object k2, object k3): |
357 | 361 | cdef Py_ssize_t h = (<Py_ssize_t><void *>k1 + 13*<Py_ssize_t><void *>k2 ^ 503*<Py_ssize_t><void *>k3) |
358 | | #if h < 0: h = -h # shouldn't "%" result in a positive number anyway? |
| 362 | # Beware that the C "%" operator returns negative values if the input |
| 363 | # is negative, which is not the case of the Python "%" operator |
| 364 | if h < 0: h = -h |
359 | 365 | cdef Py_ssize_t i |
360 | 366 | cdef list all_buckets = self.buckets |
361 | | cdef list bucket = <object>PyList_GET_ITEM(all_buckets, h % PyList_GET_SIZE(all_buckets)) |
| 367 | h = h % PyList_GET_SIZE(all_buckets) |
| 368 | cdef list bucket = <object>PyList_GET_ITEM(all_buckets, h) |
362 | 369 | cdef object tmp |
363 | 370 | for i from 0 <= i < PyList_GET_SIZE(bucket) by 4: |
364 | 371 | tmp = <object>PyList_GET_ITEM(bucket, i) |
… |
… |
|
396 | 403 | cdef Py_ssize_t h3 = <Py_ssize_t><void *>k3 |
397 | 404 | |
398 | 405 | cdef Py_ssize_t h = (h1 + 13*h2 ^ 503*h3) |
399 | | #if h < 0: h = -h # shouldn't "%" return a positive number anyway? |
| 406 | # Beware that the C "%" operator returns negative values if the input |
| 407 | # is negative, which is not the case of the Python "%" operator |
| 408 | if h < 0: h = -h |
| 409 | h = h % PyList_GET_SIZE(self.buckets) |
400 | 410 | cdef Py_ssize_t i |
401 | | cdef list bucket = <object>PyList_GET_ITEM(self.buckets, h % PyList_GET_SIZE(self.buckets)) |
| 411 | cdef list bucket = <object>PyList_GET_ITEM(self.buckets, h) |
402 | 412 | cdef object tmp |
403 | 413 | for i from 0 <= i < PyList_GET_SIZE(bucket) by 4: |
404 | 414 | tmp = <object>PyList_GET_ITEM(bucket, i) |
… |
… |
|
450 | 460 | except (TypeError,ValueError): |
451 | 461 | raise KeyError, k |
452 | 462 | cdef Py_ssize_t h = (<Py_ssize_t><void *>k1 + 13*<Py_ssize_t><void *>k2 ^ 503*<Py_ssize_t><void *>k3) |
453 | | #if h < 0: h = -h |
| 463 | # Beware that the C "%" operator returns negative values if the input |
| 464 | # is negative, which is not the case of the Python "%" operator |
| 465 | if h < 0: h = -h |
| 466 | h = h % PyList_GET_SIZE(self.buckets) |
454 | 467 | cdef Py_ssize_t i |
455 | | cdef list bucket = <object>PyList_GET_ITEM(self.buckets, h % PyList_GET_SIZE(self.buckets)) |
| 468 | cdef list bucket = <object>PyList_GET_ITEM(self.buckets, h) |
456 | 469 | for i from 0 <= i < PyList_GET_SIZE(bucket) by 4: |
457 | 470 | if <Py_ssize_t><object>PyList_GET_ITEM(bucket, i) == <Py_ssize_t><void *>k1 and \ |
458 | 471 | <Py_ssize_t><object>PyList_GET_ITEM(bucket, i+1) == <Py_ssize_t><void *>k2 and \ |
… |
… |
|
492 | 505 | cdef object v |
493 | 506 | for bucket in old_buckets: |
494 | 507 | for i from 0 <= i < PyList_GET_SIZE(bucket) by 4: |
495 | | k1 = <Py_ssize_t><object>PyList_GET_ITEM(bucket,i) |
496 | | k2 = <Py_ssize_t><object>PyList_GET_ITEM(bucket,i+1) |
497 | | k3 = <Py_ssize_t><object>PyList_GET_ITEM(bucket,i+2) |
498 | | v = <object>PyList_GET_ITEM(bucket,i+3) |
499 | | h = (k1 + 13*k2 ^ 503*k3) % buckets # the new hash |
| 508 | k1 = <Py_ssize_t><object>PyList_GET_ITEM(bucket, i) |
| 509 | k2 = <Py_ssize_t><object>PyList_GET_ITEM(bucket, i+1) |
| 510 | k3 = <Py_ssize_t><object>PyList_GET_ITEM(bucket, i+2) |
| 511 | v = <object>PyList_GET_ITEM(bucket, i+3) |
| 512 | h = (k1 + 13*k2 ^ 503*k3) |
| 513 | # Beware that the C "%" operator returns negative values if the input |
| 514 | # is negative, which is not the case of the Python "%" operator |
| 515 | if h < 0: h = -h |
| 516 | h = h % buckets # the new hash |
500 | 517 | self.buckets[h] += [k1,k2,k3,v] |
501 | 518 | |
502 | 519 | def iteritems(self): |