Search code examples
cpython-3.xportinginteger-overflow

Overflowing ints in python


I'm converting a piece of Ian Bell's Elite from C to Python. The C (ab)uses 16-bit integers, which overflow. Python uses magical Python integers, which do not. This is a problem.

I could just define a class UInt16: (UPDATE: Or use ctype's built in UInt16) which behaves like I want it to, but then I'd have to "force" every number in the entire program to be a UInt16. Is there any way I can tell my interpreter "Hey, you know Int? Well, I'd like you to use this class every place you would normally use one of those."

Or, failing that, is there another easy way I could implement integer overflow?


Solution

  • Short answer: it is not possible to override default integer behaviour as you would desire.


    Longer answer:

    Firstly, we can see that several implementations for 16-bit unsigned integer exists in Python:

    1. In built-in library ctypes 16-bit unsigned integer is available as c_uint16
    2. Numpy library also contains unint16
    3. Implementing your own uint16 data type (with operator overloading etc.)

    The question whether we can use these or some other data types to override default integer in Python is trickier.

    Let's assume that user creates all integers in the program using int method. If this is the case, then we can wrap the int method to create unsigned integer instead of regular integer:

    from ctypes import c_uint16
    _int = int
    
    def int(x):
        return c_uint16(x)
    

    For example the following code works just fine:

    a = int(1)
    

    As we can inspect:

    >>> type(a)
    <class 'ctypes.c_ushort'>
    

    By here comes the problem:

    b = 1
    

    In this case int method is not invoked, but instead, b is simply assigned value 1. What we would wish to do would be to override this behaviour too, but unfortunately it is not possible.