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: Improved two's complement arithmetic support: to_signed() and to_unsigned()
Type: enhancement Stage: resolved
Components: Interpreter Core, Library (Lib) Versions: Python 3.3
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: cvrebert, eric.smith, mark.dickinson, ncoghlan, pitrou, serhiy.storchaka, vstinner
Priority: normal Keywords:

Created on 2011-12-06 00:49 by ncoghlan, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (7)
msg148896 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2011-12-06 00:49
This RFE proposes two new methods "to_signed" and "to_unsigned" on 'int' objects and on the numbers.Integral ABC.

Semantics (and number.Integral implementation):

def to_unsigned(self, bits):
  "Convert this integer to its unsigned two's complement equivalent for the given bit length"
  if self.bit_length() >= bits:
       raise ValueError("{} is too large for {}-bit two's complement
precision".format(self, bits))
  if self >= 0:
       return self
  return 2**bits + self # self is known to be negative at this point

def to_signed(self, bits):
  "Convert an integer in two's complement format to its signed equivalent for the given bit length"
  if self < 0:
       raise ValueError("{} is already signed".format(self))
  if self.bit_length() > bits:
       raise ValueError("{} is too large for {}-bit two's complement
precision".format(self, bits))
  upper_bound = 2**bits
  if self < (upper_bound / 2):
     return self
  return upper_bound - self

To add these methods to numbers.Integral, a concrete numbers.Integral.bit_length() operation will also be needed. This can be implemented simply as:

def bit_length(self):
    return int(self).bit_length()

(Initial concept from this python-ideas thread: http://mail.python.org/pipermail/python-ideas/2011-December/012989.html)
msg148909 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-12-06 10:37
Instead of requiring bit_length(), couldn't you simply compare self to 2**(bits-1) (for to_unsigned) and 2**bits (for to_signed)?
msg148929 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2011-12-06 19:24
The 'self.bit_length() >= bits' condition for to_unsigned doesn't look right to me.

E.g., if bits == 32, I'd expect the acceptable range of values to be range(-2**31, 2**31)---i.e., including -2**31, but excluding 2**31.  But the ValueError for 'self.bit_length() >= 32' means that -2**31 is excluded.
msg148930 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2011-12-06 19:35
On the feature request itself, I have to say that I'm unconvinced.  Doing x % (2**32) seems good enough to me, in situations where you don't need the bounds checking.  (And it's not clear to me that needing the bounds checks is the more common situation.)
msg148931 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-12-06 19:39
> On the feature request itself, I have to say that I'm unconvinced.
> Doing x % (2**32) seems good enough to me, in situations where you
> don't need the bounds checking.

Ah, I didn't know that modulo worked for that. Nice trick.
msg252412 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-10-06 17:21
I'm for closing this issue. This is not the common operation.
msg289189 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-03-07 21:33
If you open the can of worms, other features will be requested like uint32+uint32 which would silently overflow.

IMHO it would be better to have a package (on PyPI) providing integers of fixed size implementing two's complement arithmetic: int8, uint16, etc. I failed to find an existing module.
History
Date User Action Args
2022-04-11 14:57:24adminsetgithub: 57744
2017-03-07 21:33:01vstinnersetmessages: + msg289189
2017-03-07 19:17:33serhiy.storchakasetstatus: pending -> closed
resolution: rejected
stage: needs patch -> resolved
2015-10-06 17:21:03serhiy.storchakasetstatus: open -> pending
nosy: + serhiy.storchaka
messages: + msg252412

2011-12-06 20:07:07vstinnersetnosy: + vstinner
2011-12-06 19:39:21pitrousetmessages: + msg148931
2011-12-06 19:35:54mark.dickinsonsetmessages: + msg148930
2011-12-06 19:24:47mark.dickinsonsetmessages: + msg148929
2011-12-06 19:18:09mark.dickinsonsetnosy: + mark.dickinson
2011-12-06 10:37:59pitrousetnosy: + pitrou
messages: + msg148909
2011-12-06 01:26:22cvrebertsetnosy: + cvrebert
2011-12-06 00:54:40eric.smithsetnosy: + eric.smith
2011-12-06 00:49:34ncoghlancreate