This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: decimal.py: logb: round the result if it is greater than prec
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 3.1, Python 3.2, Python 2.7, Python 2.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: mark.dickinson Nosy List: mark.dickinson, rhettinger, skrah
Priority: normal Keywords: patch

Created on 2009-10-03 13:53 by skrah, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
logb_additional.decTest mark.dickinson, 2009-10-07 09:33
decimal_testcases.patch mark.dickinson, 2009-10-07 17:46 Update testcases
logb.patch mark.dickinson, 2009-10-07 17:49
scaleb.patch mark.dickinson, 2009-11-28 14:43
Messages (18)
msg93492 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2009-10-03 13:53
>>> from decimal import *
>>> c = getcontext()
>>> c.prec = 2
>>> c.logb(Decimal("1E123456"))
Decimal('123456')
>>> 

This result agrees with the result of decNumber, but the spec says:
"All results are exact unless an integer result does not fit in the
available precision."

My interpretation is that the result should be 1.2E+5.
msg93500 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-03 16:10
Hmm.  The problem here is that the specification says nothing at all 
about what should happen if the integer result does *not* fit in the 
available precision, so in this case we went with the decNumber 
behaviour.

Rather than rounding, I'd say that a more useful result in this case 
would be to signal InvalidOperation, on the basis that an inexact result 
from logb is likely to invalidate most uses of it.

Maybe we should ask Mike Cowlishaw what the intended behaviour here is?

IEEE 754-2008 (section 5.3.3) requires that languages define a 
'logBFormat' type that's always big enough to hold the logB result.  If 
the result is a Decimal, one way to ensure this would be to place 
constraints on the allowable values emax and emin for a given precision.
msg93686 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-07 09:26
(Stefan emailed Mike Cowlishaw about this:  thanks, Stefan!)

Mike's initial response suggests that we *should* be rounding the result
here.  That is, decNumber and decimal.py are both in error, and Stefan's
interpretation is correct.
msg93687 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-07 09:33
Attaching additional testcases from Mike Cowlishaw.
msg93703 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-10-07 17:04
Mike's response makes sense to me.  If the precision is 2, the result
should round to that precision.  The documents showing the theory behind
the decimal spec indicate that in general mathematical operations are
exact, only the results get rounded.   Also IIRC, the use of
InvalidOperation is limited to the mathematical part, not the rounding step.
msg93704 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-07 17:46
Patch to update to the most recent official set of tests.

With this patch, logb and scaleb fail.
msg93705 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-07 17:49
Patch to fix logb.
msg93706 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-07 17:56
I don't understand the new scaleb testcases (from Mike).  They look like 
this:

precision:   34
maxExponent: 999999999
minExponent: -999999999
-- integer overflow in 3.61 or earlier
scbx164 scaleb  1E-999999999  -1200000000  -> NaN Invalid_operation
-- out of range
scbx165 scaleb  -1E-999999999  +1200000000  -> NaN Invalid_operation

The specification says that the second operand should be in the range 
+/-2*(Emax+precision) inclusive, which in this case it is.  So clearly 
there are additional situations in which Invalid_operation should be 
signalled.  It's not clear to me what those conditions are.
msg93707 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-07 18:02
The IEEE 754-2008 description of scaleB makes a lot more sense, IMO:
scaleB(x, N) is simply x*10**N (assuming that B=10 and N is integral), 
rounded in the usual way.

The restriction in the specification seems arbitrary and questionable.  
Presumably it's intended to aid implementation in low-level languages.
msg93715 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-07 19:26
Applied the fix for logb in r75275 (trunk), r75276 (py3k) and r75277 
(release31-maint).  r75275 still needs to be merged to the release26-maint 
branch once it's unfrozen.
msg93718 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2009-10-07 20:13
precision:   34
maxExponent: 999999999
minExponent: -999999999
-- integer overflow in 3.61 or earlier
scbx164 scaleb  1E-999999999  -1200000000  -> NaN Invalid_operation
-- out of range
scbx165 scaleb  -1E-999999999  +1200000000  -> NaN Invalid_operation

I would say that this is implementation specific, as a workaround for
the overflow. This isn't in the spec at the moment.
msg93749 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-08 16:34
I've updated to the newest version of the test-suite in r75285 through 
r75287.  As before, r75285 needs to be backported to the 2.6 maintenance 
branch once its unfrozen.

I'm currently skipping those two scaleb tests, until we work out what 
should be going on here.
msg94277 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-20 13:59
I just want to note another problem with logb:  it doesn't use the correct 
context when processing NaNs.  This needs a test and a fix.
msg94278 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-20 14:07
Sorry;  ignore that last.  I was confused by the fact that the _check_nans 
call came before the 'if context is None' test.  But _check_nans deals 
correctly with a context of None, so logb is fine.
msg94563 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-27 16:56
logb fix applied to release26-maint in r75804.
msg94565 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-10-27 17:03
Updated release26-maint to new test-suite in r75806.
msg95788 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-11-28 14:43
There's a restriction on the second argument to scaleb in the spec, 
namely that scaleb should be in the range -2*(Emax + precision) to 
2*(Emax + precision) inclusive.

This restriction seems entirely arbitrary and unnecessary to me.  My
guess is that it's there to ease implementation in low-level languages, 
but it makes little sense for the Python implementation.

Here's a patch that removes this restriction on scaleb in the Python 
implementation, and skips the corresponding tests.
msg95960 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-12-04 11:10
Mike Cowlishaw has confirmed that the tests scbx164, scbx165 (in version 
2.59 of the tests) are implementation-specific, so test_decimal is doing 
the right thing in skipping them.  So I think this issue can be closed.

I don't think it's worth removing the restriction on the 2nd scaleb 
argument:  while I still think it's arbitrary and unnecessary, keeping it 
allows us to say that we're in full compliance with the specification.
History
Date User Action Args
2022-04-11 14:56:53adminsetgithub: 51297
2009-12-04 11:10:35mark.dickinsonsetstatus: open -> closed
resolution: fixed
messages: + msg95960
2009-11-28 15:54:40mark.dickinsonsetpriority: high -> normal
2009-11-28 14:43:52mark.dickinsonsetfiles: + scaleb.patch

messages: + msg95788
2009-10-27 17:03:13mark.dickinsonsetmessages: + msg94565
2009-10-27 16:56:55mark.dickinsonsetmessages: + msg94563
2009-10-20 14:07:41mark.dickinsonsetmessages: + msg94278
2009-10-20 13:59:14mark.dickinsonsetmessages: + msg94277
2009-10-08 16:34:48mark.dickinsonsetmessages: + msg93749
2009-10-07 20:13:50skrahsetmessages: + msg93718
2009-10-07 19:26:23mark.dickinsonsetmessages: + msg93715
2009-10-07 18:02:28mark.dickinsonsetmessages: + msg93707
2009-10-07 17:56:10mark.dickinsonsetmessages: + msg93706
2009-10-07 17:49:14mark.dickinsonsetfiles: + logb.patch

messages: + msg93705
2009-10-07 17:46:56mark.dickinsonsetfiles: + decimal_testcases.patch
keywords: + patch
messages: + msg93704
2009-10-07 17:04:40rhettingersetnosy: + rhettinger
messages: + msg93703
2009-10-07 09:33:00mark.dickinsonsetfiles: + logb_additional.decTest

messages: + msg93687
2009-10-07 09:26:37mark.dickinsonsetpriority: high

assignee: mark.dickinson
components: + Library (Lib)
versions: + Python 2.6, Python 3.1, Python 2.7, Python 3.2
type: behavior
messages: + msg93686
stage: test needed
2009-10-03 16:10:34mark.dickinsonsetmessages: + msg93500
2009-10-03 13:53:16skrahcreate