I am calculating the absolute difference between two numpy.uint8
s in python with
d = abs(a - b)
, which results in an overflow error if b
is bigger than a
. What's the best way to avoid this?
Asked
Active
Viewed 4,247 times
5
-
1Er... no it doesn't. Python automatically promotes integers to longs when necessary. Also, there's no unsigned integer type in Python. Please post code that demonstrates the problem you're actually having, and a traceback. – kindall Sep 26 '12 at 23:55
-
2I get a and b from an external library (pygtk) and their type is numpy.uint8. The error is RuntimeWarning: overflow encountered in ubyte_scalars. Because of this it's not possible to give a short working example. – blues Sep 26 '12 at 23:58
3 Answers
3
As your comment indicates, they aren't int
s; they're numpy.uint8
s. Just convert them to int
s:
>>> a, b = map(numpy.uint8, (50, 60))
>>> a - b
__main__:1: RuntimeWarning: overflow encountered in ubyte_scalars
246
>>> a, b = map(int, (a, b))
>>> a - b
-10
Since you are concerned about speed, here are a couple of tests (borrowing Sven's form, with thanks):
>>> %timeit abs(int(a) - int(b))
1000000 loops, best of 3: 410 ns per loop
>>> %timeit a - b if a > b else b - a
1000000 loops, best of 3: 470 ns per loop
So yes, it's faster, but unless we're talking about doing it hundreds of millions of times, it won't matter a bit.
-
Is this faster than the test Ionut suggested? Because I need to do this very often. – blues Sep 27 '12 at 00:07
-
@blues, if you have a numpy array of them (which looks a lot like a list with duck typing) you can get *much* faster probably, but if its just single values numpy can't help you with speed... – seberg Sep 27 '12 at 17:23
2
The easiest way is to manually convert your numbers to Python ints first:
d = abs(int(a) - int(b))
Python ints can't overflow (unless the memory is full).

Sven Marnach
- 574,206
- 118
- 941
- 841
0
For me it does not throw overflow error, just results in false values if b
is bigger than a
. To stay in uint8
boundaries use this function:
def abs_dev (a, b) :
sub1 = a - b
sub2 = b - a
mask = a < b
sub1[mask] = sub2[mask]
return sub1

Mikhail V
- 1,416
- 1
- 14
- 23