2

I want to do some simulation of C language calculation in Python. For example, unsigned short, single precision float ...

ushort(0xffff) + 1 -> 0
0.1f * 0.1f -> ...

Are there some library to do this in Python?

I can use ctypes to create unsigned short, single float, but they cann't do math operation:

a = c_uint16(0xffff)
b = c_uint16(0x01)
a+b -> TypeError

Or, I can use numpy:

>>> np.uint16(0xffff) + np.uint16(0x01)
Warning: overflow encountered in ushort_scalars
0

but it's very slow comparing to Python's normal calculation:

>>> timeit.timeit("a+b", "import numpy as np;a=np.uint16(0xfffe);b=np.uint16(0x01)")
0.35577465681618037
>>> timeit.timeit("0xfffe+0x01")
0.022638104432360251
>>> timeit.timeit("np.uint16(0xfffe) + np.uint16(0x01)", "import numpy as np")
5.904765399236851  

Edit:

>>> timeit.timeit("a+b", "a=0xfffe;b=0x01")
0.040062221014295574  
1
  • how about: def add(a,b): return (a+b) % 65536 ? Commented Jun 16, 2011 at 2:21

2 Answers 2

6

When compiling 0xfffe+0x01, this will be folded into the constant 65535. You aren't timing how long the addition takes -- you are just measuring the time of loading the constant:

>>> dis.dis(compile("0xfffe+0x01", "", "eval"))
  1           0 LOAD_CONST               2 (65535)
              3 RETURN_VALUE        

The addition of NumPy scalars is slower than adding built-in integers nevertheless, but it won't get better than that in pure Python. Consider using Cython -- it will allow you to declare types and execute the computations in C speed. Alternatively, try to vectorise your code in NumPy (that is, if speed really matters).

Sign up to request clarification or add additional context in comments.

2 Comments

yes, the gerund vs. infinitive thing doesn't make a lot of sense does it? I was thinking about it after I saw this. For example "try to use cython" and "try using cython" are both idiomatic English, but they mean subtly different things; the former means something like "as a rule, use cython if you can," while the latter is closer to "consider using cython." (And for what it's worth, it should probably be "to learn better English.") All that said, I did mean it, about your posts being spotless, generally. Now that I know you don't mind a direct edit, perhaps I'll do that next time.
@senderle: Thanks again -- I'll clarify the message in my profile!
1

You can make a function for each operation using modulo % with 2**sizeof (in your case, 2**16 or 65536)

def add(a, b, mod=2**16):
    return (a+b) % mod

def sub(a, b, mod=2**16):
    return (a-b) % mod

and any other function you need.

>>> add(0xffff, 1)
0
>>> sub(10, 20)
65526

Note this will work only for unsigned types. For signed ones, you can use half the value used to mod (i.e. 2**15) and will have to validate the result before applying modulo

1 Comment

Thanks, your method is useful for integers. For single floats, I am considering using ctypes call some DLL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.