Why is ROUND_HALF_EVEN superior? Perhaps for statistics, where rounding all halves up would skew results, but I guess not for most other cases.
If the default rounding behaviour produces different results than a regular calculator, common spreadsheet and accounting software or even human (mentally adding numbers) would, then I think the default behaviour is surprising to many users. I was certainly surprised when I first encountered it, not being familiar with Python's default of ROUND_HALF_EVEN. I don't see an easy way for users to change the default rounding behaviour for `DecimalField`. Would it be considered backwards incompatible to change the default to ROUND_HALF_UP? If so, would it be easy enough to make it possible for users to easily change the default behaviour for a single field or even project-wide? I hate to suggest adding another setting, but might it be necessary for some users to change the rounding behaviour of DecimalField that is defined in a 3rd party app? On a related note, the `floatformat` template tag explicitly uses ROUND_HALF_UP. I think we should at least be consistent. And if there's cause to allow users to change the behaviour for DecimalField, they should probably be able to change `floatformat` as well. I agree that a no_rounding argument would also be good, in addition to being able to specify the rounding method to use. Cheers. Tai. On Oct 6, 11:45 am, Paul McMillan <p...@mcmillan.ws> wrote: > > .. (A) silent rounding issue: > > when a decimal value is saved in db > > its decimal digits exceeding decimal_places are rounded off using > > .quantize(). Rounding defaults to ROUND_HALF_EVEN (python default). > > There is no mention of this behavior in docs. > > Docs patches welcomed. This rounding behavior is generally superior to > ROUND_UP (what most of us are taught in gradeschool) for a number of > reasons that are inappropriate to get into here. If we're going to > round, that's the behavior we should use as default. > > > .. (B) no model validation for decimal digits: > > .full_clean() does not raise any exception: > > - if the value has too many decimal digits > > - or if value has too many digits > > other fields, like CharField, do not validate values that exceed fields > > constraints > > There's no clearly defined way to deal with overlong CharFields. > Rounding overlong floating point numbers is common and not unexpected. > Decimals work similarly to floats, and so it's not unreasonable to > have similar behavior. > > Reading the docs on Python's decimal module, it makes sense to think > of the decimal_places as an analog to python's decimal notion of > precision.http://docs.python.org/library/decimal.html#module-decimal > > > .. (C) errors on save: > > decimal values exceeding field's digits boundaries (decimal or total) make > > .save() raise decimal.InvalidOperation exceptions > > This does sound like an error in validation. If it's possible to pass > a value through form validation to the point where it has errors on > save, that is a bug. > > > In my opinion they should be fixed in a backwards-incompatible way!: > > Thank you for your opinion, we don't do backwards-incompatible fixes. > There's usually a compatible way to fix behavior. > > > (A) django shuld not round decimal values silently before saving, if the > > value has too many decimal digits, > > raise an exception (just like for values that have too many digits) > > In the general use case, the existing behavior is more user friendly. > Many people would run out and re-add the rounding behavior if we > changed it. Users will enter over-long strings into decimal fields. > It's really unfriendly to paste an 32 place decimal number in and be > told it can only be 17 decimal digits long (and then have to go count > out till you get the correct number). Since there's not a good way to > make this the default value and retain backwards compatibility, this > is unlikely to change. This behavior should be documented. > > That said, a no_rounding kwarg sounds like a perfectly reasonable feature. > > > (B) decimalfield shoud not validate values that exceed its max_digits and > > decimal_places constraints > > I agree that decimalfield should not validate values that exceed > max_digits. If it does, that is a bug we should fix. We need to be > careful not to create situations where very large numbers validate but > very small but precise decimal numbers get rounded unexpectedly. > Unfortunately, these two parameters overlap in difficult ways. I > disagree about decimal_places, since the expected behavior is rounding > in most other real-world circumstances. > > Does the combination of documenting the existing rounding behavior, > fixing the error on save() with max_digits, and adding the no_rounding > feature address your concerns? > > -Paul -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.