cmp() on integers - is there guarantee of returning only +-1 or 0?

D

Dmitry Anikin

doc says that it must be > 0, or < 0, but it seems that
it returns +1 or -1. Can it be reliably used to get the sign of x:
cmp(x, 0) like pascal Sign() function does? I mean, I'm
pretty sure that it can be used, but is it mentioned somewhere
in language spec, or it may be implementation defined?
If so, any other simple means of _reliably_ getting the sign?
 
P

Paul Rubin

Dmitry Anikin said:
doc says that it must be > 0, or < 0, but it seems that
it returns +1 or -1. Can it be reliably used to get the sign of x:
cmp(x, 0) like pascal Sign() function does?

The doc says (http://docs.python.org/lib/built-in-funcs.html):

cmp(x,y)
Compare the two objects x and y and return an integer according
to the outcome. The return value is negative if x < y, zero if
x == y and strictly positive if x > y.
I mean, I'm pretty sure that it can be used, but is it mentioned
somewhere in language spec, or it may be implementation defined?

The doc doesn't specify that it returns -1/0/+1 so by definition
it's implementation defined.
If so, any other simple means of _reliably_ getting the sign?

Ehh, every way I see offhand is at least a little bit messy.
 
W

wittempj

It is depending on the classes you try to compare, and on how the
comparison functions (see
http://docs.python.org/ref/customization.html) are implemented in
these, see example below:

py> class wrong(object):
.... def __init__(self, x):
.... self.x = x
.... def __cmp__(self, other):
.... if self.x < other.x:
.... return -1
.... else:
.... return 1
....
py> class right(object):
.... def __init__(self, x):
.... self.x = x
.... def __cmp__(self, other):
.... if self.x < other.x:
.... return -1
.... elif self.x > other.x:
.... return 1
.... else:
.... return 0
....
py> w1 = wrong(1)
py> w2 = wrong(1)
py> cmp(w1, w2)
1
py>
py> r1 = right(1)
py> r2 = right(1)
py> cmp(r1, r2)
0
 
S

skip

Dmitry> doc says that it must be > 0, or < 0, but it seems that it
Dmitry> returns +1 or -1. Can it be reliably used to get the sign of x:
Dmitry> cmp(x, 0) like pascal Sign() function does?

Why not

def sign(n):
return n and n/abs(n) or 0

Skip
 
S

skip

def sign(n):
return n and n/abs(n) or 0

Whoops... Make that

def sign(n):
return n and n/abs(n) or 1

Skip
 
A

Alex Martelli

Dmitry> doc says that it must be > 0, or < 0, but it seems that it
Dmitry> returns +1 or -1. Can it be reliably used to get the sign of x:
Dmitry> cmp(x, 0) like pascal Sign() function does?

Why not

def sign(n):
return n and n/abs(n) or 0

If you assume n is a number, the 'or 0' appears redundant (if you don't
so assume, then the abs(n) and the division are doubtful;-).


Alex
 
A

Alex Martelli

def sign(n):
return n and n/abs(n) or 0

Whoops... Make that

def sign(n):
return n and n/abs(n) or 1

Uh? I thought part of the specs was that sign(0) is 0...


Alex
 
C

Christoph Zwerschke

Alex said:
If you assume n is a number, the 'or 0' appears redundant (if you don't
so assume, then the abs(n) and the division are doubtful;-).

Without the 'or 0' it is also more consistent with the behavior of your
function that the sign of a float is also a float.

One issue is that division should be normally avoided because it is a
costly operation and can lead to rounding errors. Maybe performance is
is not a problem for ints and floats, but if you are planning to use the
function on long ints, I would consider using something like:

def sign(x): return x>0 and 1 or x<0 and -1 or 0

def sign(x): return (x>0)-(x<0)

-- Christoph
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top