#32555: DecimalField Rounding inconsistency (PostgreSQL)
-------------------------------------+-------------------------------------
               Reporter:  bluppfisk  |          Owner:  nobody
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  2.2
  layer (models, ORM)                |       Keywords:  decimalfield,
               Severity:  Normal     |  rounding, float
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Note, I've initially posted this on
 [https://stackoverflow.com/questions/66644473/django-decimalfield-
 inconsistent-rounding stackoverflow]

 Django 2.2, PostgreSQL database. I have a `Line` object with a `positions`
 property. This is an `ArrayField` of a `DecimalField` with a `max_digits`
 of 12 and `decimal_places` of 3.

 I store some floats as `Decimal`s and get them back out of the Database:

 {{{
 pos = [6586.87849502, 2.04190477e-01, 7.14666669e-01]
 line = Line(positions=pos)
 line.save()
 line.refresh_from_db()  # send it through Django's ORM piping
 print(line.positions)
 }}}
 Output:

 > [Decimal('6586.87**9**'), Decimal('0.204'), Decimal('0.715')]

 Interestingly, the first position was rounded up despite its next more
 significant digit being below 5. The other float is rounded down as
 expected.

 I thought it might be PostgreSQL messing around, but no:

 {{{
 INSERT INTO line(positions) VALUES (array[6586.87849502, 2.04190477e-01,
 7.14666669e-01]) RETURNING positions;
 }}}

 > positions (numeric[])
 > {6586.878,0.204,0.715}


 The real issue is that I should be able to predict what will come out of
 the database, down to the required precision of three decimal places:

 {{{
 [Decimal(x).quantize(Decimal("0.001")) for x in pos]
 }}}

 might yield

 > [Decimal('6586.878'), Decimal('0.204'), Decimal('0.715')]

 or

 > [Decimal('6586.879'), Decimal('0.205'), Decimal('0.714')]

 depending on the `decimal.ROUND_*` flag I pass in `quantize()`, but I
 never get consistent rounding throughout the array.

 I also tried using the `django.db.backends.util::number_format` function
 for every of my `Decimal`s as I gathered that this is used by Django
 before inserting into the database, but the results are still
 inconsistent.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32555>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/052.bff1f31857cff4578c404c2cb6f1d60f%40djangoproject.com.

Reply via email to