-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Context._clamp public in decimal module #52786
Comments
The Context class in the decimal module has a hidden _clamp attribute, that controls whether to clamp values with large exponents. (Clamping a Decimal value involves adding extra significant zeros to decrease its exponent, while not altering the numeric value; it's sometimes necessary to get the exponent within a legal range). I think we should consider making this attribute public (documenting it, having it appear in the __str__ or __repr__ of a Context), for a couple of reasons: (1) It's necessary for full compliance with the specification: Python's default behaviour is actually non-compliant with the spec; it's only after doing getcontext()._clamp = 1 that it complies. (2) Clamping is necessary for modeling the standard formats described in IEEE 754-2008 (decimal64, decimal128), etc. These formats are coming into use in other languages (gcc already supports them and C201x may well include them). To be able to communicate effectively with other languages using these formats, it would be useful to expose Context._clamp. |
(1) Perhaps I missed the relevant part in the spec, so I had to check (2) I agree about the importance of the formats, and I think they should http://java.sun.com/j2se/1.5.0/docs/api/java/math/class-use/MathContext.html The current ExtendedContext is a bit of a vague concept, since it |
I knew it was somewhere: In the test case description, clamp=0 is |
Hmm. Yes, the spec itself is rather vague on the subject of clamping, so I withdraw my claim that clamping is necessary for compliance with the spec. It *is* necessary to make the those testcases with 'clamp=1' pass, though. So from the point of view of compliance with the specification it's fine to leave the _clamp attribute private. I agree it would be useful to give easy access to the IEEE 754 formats, though, for interoperability with C and Java (thanks for the Java link!). The most important formats are decimal32, decimal64 and decimal128, but IEEE 754 also specifies parameters for decimal{k} where k is any multiple of 32 bits. |
Re: ExtendedContext, the comments in decimal.py say: # Pre-made alternate contexts offered by the specification This doesn't make a lot of sense to me, since (as Stefan says) the choice of precision 9 doesn't seem to come from the specification. However, the current ExtendedContext is used extensively in doctests and elsewhere; it would be awkward to change it now. I think adding the IEEE formats and encouraging users to use those in place of ExtendedContext might be the best bet. I'd also still want to make _clamp public in this case, to avoid people wondering why two apparently identical contexts (one with _clamp=1, one with _clamp=0) can lead to different results. |
I'd prefer to drop the ExtendedContext completely. Reasons are:
I can see that it is awkward to remove it, but if there's consensus Making clamp visible sounds fine to me. (Personally, I'd rather have If we make Decimal{32,64,128} contexts available, we should document exactly how the arithmetic deviates from IEEE754. |
We have to be careful not to break existing 3rd party code, though. A newly-designed decimal module, prepared with 20/20 hindsight, probably wouldn't include an ExtendedContext with the current definition. But we're not dealing with a newly-designed module: we're dealing with a well-established and well-used module, so there's not a lot of scope for removals or major behaviour changes. Personally, I don't think the design error (if there is a design error here) is big enough to make it worth breaking backwards compatibility. I'd rather leave ExtendedContext in for the duration of Python 3.x, but introduce better options and steer (via the documentation) new decimal users towards those. (BTW, Python takes backwards compatibility pretty seriously: see PEP-387 for a write-up of the policy.)
Possibly, though that's less important to me than just being able to read and write values in these formats produced by other systems. Were you thinking of any deviations in particular? Making clamp public should be straightforward enough though, and is independent of the changes discussed above; I'll see if I can come up with a patch. (Even here, though, I think it makes sense to leave the private _clamp attribute in place in case people are using it; a new public 'clamp' property can be added that wraps the _clamp attribute.) |
More or less a commentary on what is listed here: http://speleotrove.com/decimal/dascope.html ==> Restrictions I only have a draft of IEEE754, but for instance I can't find a power |
I'm busy implementing the IEEE754 contexts for cdecimal. To keep things Suggestions:
I have a preference for 2). It's clear that you get a new Object and (I know there are measures against that, but setcontext( Context(Decimal64)) |
Rather that complicating the Context constructor, I'd prefer a separate factory function. I was thinking of something like: def IEEEContext(n):
"""Return the decimal<n> IEEE 754 context. n should be a multiple
of 32."""
... Again, it's clear with this that you get a new context object (I agree that there are problems with (1) and the mutability of Contexts). |
BTW, let's open another issue for support of the IEEE 754 contexts, and keep this one for exposing _clamp. Otherwise life gets confusing when you're trying to decide when an issue can be closed, etc... |
Here's a patch for changing '_clamp' into 'clamp'. |
The patch looks good, +1 for applying it. I'm not a native speaker, but "are subject to clamping this manner" => "are subject to clamping in this manner" |
Thanks for catching the doc typo! Actually, I didn't like that doc addition anyway, so I rewrote it. Committed in r81476. |
New changeset 221638ba5d2a by Mark Dickinson in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: