Decide if a number is negative or positive?

J

Johs

I need to make some special action if 'a' and 'b' are both positive or
both negative. Is there some inbuilt function to check this?

Johs
 
R

Richard Heathfield

Johs said:
I need to make some special action if 'a' and 'b' are both positive or
both negative. Is there some inbuilt function to check this?

How about zero, which is neither positive or negative?

With that caveat, consider this:

#define SAME_SIGN(a, b) ((((a)<0)==((b)<0))&&(((a)>0)==((b)>0)))
 
R

Richard Tobin

I need to make some special action if 'a' and 'b' are both positive or
both negative. Is there some inbuilt function to check this?
[/QUOTE]
How about zero, which is neither positive or negative?

And if either of the values may be a floating-point number, you need
to consider how you want -0 (which is distinct from +0 in some
floating point systems) to behave.

-- Richard
 
T

Taran

Johs said:
I need to make some special action if 'a' and 'b' are both positive or
both negative. Is there some inbuilt function to check this?

Johs

I am not really sure if there is an inbuilt function or not. AFAIK it
would take less time to code it than to find that special function if
it was available.

Anyways here's the code, not tested though:

/* product of two positive or two negative numbers is always positive
* and equality with zero takes care of the special case 0.
*/
if ( (a* b) >= 0 )
{
/* the numbers are either both positive or both negative
*/
}

This will also remove the the conflict between +0 and -0, which ever
type of signed 0 it is, they both must be of the same sign.

Sometimes we have to live with non-sense like +0 or -0.

HTH
 
C

Chris Dollin

Taran said:
I am not really sure if there is an inbuilt function or not. AFAIK it
would take less time to code it than to find that special function if
it was available.

Anyways here's the code, not tested though:

/* product of two positive or two negative numbers is always positive
* and equality with zero takes care of the special case 0.
*/
if ( (a* b) >= 0 )
{
/* the numbers are either both positive or both negative

Or the product can't be represented as a value of the appropriate
kind. This is a Very Bad Way to try and solve the problem.

I don't see why

if (a > 0 && b > 0 || a < 0 && b < 0) ... co-signed ...

(fiddle with >=, <= to taste) isn't good enough. Or

if (a < 0 == b < 0) ... co-signed ...
 
C

CBFalconer

Richard said:
And if either of the values may be a floating-point number, you
need to consider how you want -0 (which is distinct from +0 in
some floating point systems) to behave.

I believe the standards commitee has found that there are no
implementations extant where insistance on all bits zero will fail
to simulate 0.0, and thus plan to allow that in the future. NULL
is another matter, but usually works. Document any such usage as
non-portable.
 
O

osmium

Johs said:
I need to make some special action if 'a' and 'b' are both positive or both
negative. Is there some inbuilt function to check this?

No, there is no built in function to do this. The best way, in general, to
answer this kind of thing in the future is to take a good reference, such as
the appendix in K&R, and make some personal notes on the various headers.
This will force you to actually read, rather than skim, the contents. Most
everything will fit into some kind of category, but you really need to
study <stdlib.h> because it is a catch all for the residue of what didn't
fit in some neat niche. And <math.h> should be studied as well.

IMO the people that wrote the standard were pretty careful not to innundate
the thing with drivel. I consider something as pointless when it is trivial
and obvious to do it with the basic language. But everyone has their own
personal "trivial" of course. The "pointless" functions along the lines of
what you asked that comes to mind is abs() and fabs(). Some of the stuff
may be trivial but not obvious, ceil() and floor() in <math.h>come to mind.

But in a practical sense this still leaves the question, OK, it is not
standard but "Does *my* compiler have such a function?" For example, there
might be something special to convert "endinadness". I don't have any
particularly helpful hints on that problem. Study and practice, practice,
practice AFAIK.
 
D

David T. Ashley

Johs said:
I need to make some special action if 'a' and 'b' are both positive or both
negative. Is there some inbuilt function to check this?

Johs

If they are both signed integers of the same size, the easiest way to test
for both positive or both negative is probably something like:

(a ^ b) >= 0

I'm naturally making the assumption of standard 2's complement
representation (and I haven't seen a machine that doesn't support this, but
I don't know what standards apply).

This assumes that the machine hardware economically fetches an integer in
one instruction. If not, one needs only to test the upper byte or word of
each.
 
K

Kenneth Brody

Johs said:
I need to make some special action if 'a' and 'b' are both positive or
both negative. Is there some inbuilt function to check this?

If by "positive" you really mean "non-negative" (ie: including zero),
then this (*untested*) should work:

#define SAME_SIGN(a,b) ( ((a)<0) == ((b)<0) )

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
R

Richard Tobin

And if either of the values may be a floating-point number, you
need to consider how you want -0 (which is distinct from +0 in
some floating point systems) to behave.
[/QUOTE]
I believe the standards commitee has found that there are no
implementations extant where insistance on all bits zero will fail
to simulate 0.0, and thus plan to allow that in the future.

I don't see the relevance of this to the question. I was pointing out
that the OP must decide whether he wants to consider -0 and +0 as
having the same sign or not; this has nothing to do with the
representation.

-- Richard
 
K

Keith Thompson

CBFalconer said:
I believe the standards commitee has found that there are no
implementations extant where insistance on all bits zero will fail
to simulate 0.0, and thus plan to allow that in the future. NULL
is another matter, but usually works. Document any such usage as
non-portable.

Apart from not being, as far as I can see, relevant to the point, I
haven't heard anything about all-bits-zero being universally a
representation for 0.0. It wasn't until relatively recently
(post-C99) that the committee decided that all-bits-zero is always a
representation of 0 for integer types; could that be what you're
thinking of?
 
K

Keith Thompson

David T. Ashley said:
If they are both signed integers of the same size, the easiest way to test
for both positive or both negative is probably something like:

(a ^ b) >= 0

I'm naturally making the assumption of standard 2's complement
representation (and I haven't seen a machine that doesn't support this, but
I don't know what standards apply).

This assumes that the machine hardware economically fetches an integer in
one instruction. If not, one needs only to test the upper byte or word of
each.

This is an obscure way to go about it. The standard doesn't require a
2's complement representation for signed integers, though it's almost
universal these days. The fact that you talk about testing only the
upper byte or word of each operand tells me you're thinking in terms
of micro-optimization, which is usually a bad idea *unless* you've
confirmed that the code in question is a significant performance
bottleneck.

(Personally, I wouldn't try to use bitwise operations on signed
integers; I've never bothered to learn how they behave. If I ever
need to know, I'll look it up.)

Also, the OP didn't say he's working with integers.

Just write the code as clearly as possible, such as:

(a >= 0 && b >= 0) || (a < 0 && b < 0)

or even

(a >= 0) == (b >= 0)
 
J

Joe Wright

Keith said:
This is an obscure way to go about it. The standard doesn't require a
2's complement representation for signed integers, though it's almost
universal these days. The fact that you talk about testing only the
upper byte or word of each operand tells me you're thinking in terms
of micro-optimization, which is usually a bad idea *unless* you've
confirmed that the code in question is a significant performance
bottleneck.

(Personally, I wouldn't try to use bitwise operations on signed
integers; I've never bothered to learn how they behave. If I ever
need to know, I'll look it up.)

Also, the OP didn't say he's working with integers.

Just write the code as clearly as possible, such as:

(a >= 0 && b >= 0) || (a < 0 && b < 0)

or even

(a >= 0) == (b >= 0)
or even

!(a < 0) ^ !(b < 0)
 
P

pete

Joe said:
Keith Thompson wrote:
or even

!(a < 0) ^ !(b < 0)

Not even.
He said "as clearly as possible" for a reason.

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
int a, b;

puts("/* BEGIN new.c output */\n");
for (a = -1; a != 2; ++a) {
for (b = -1; b != 2; ++b) {
printf("a is %d\nb is %d\n", a, b);
printf("(a >= 0 && b >= 0) || (a < 0 && b < 0) is %d\n",
(a >= 0 && b >= 0) || (a < 0 && b < 0));
printf("(a >= 0) == (b >= 0) is %d\n",
(a >= 0) == (b >= 0));
printf("!(a < 0) ^ !(b < 0) is %d\n",
!(a < 0) ^ !(b < 0));
putchar('\n');
}
}
puts("/* END new.c output */");
return 0;
}

/* END new.c */
 
C

CBFalconer

Keith said:
.... snip ...

Apart from not being, as far as I can see, relevant to the point,
I haven't heard anything about all-bits-zero being universally a
representation for 0.0. It wasn't until relatively recently
(post-C99) that the committee decided that all-bits-zero is
always a representation of 0 for integer types; could that be
what you're thinking of?

Probably.
 
D

David T. Ashley

Keith Thompson said:
This is an obscure way to go about it. The standard doesn't require a
2's complement representation for signed integers, though it's almost
universal these days. The fact that you talk about testing only the
upper byte or word of each operand tells me you're thinking in terms
of micro-optimization, which is usually a bad idea *unless* you've
confirmed that the code in question is a significant performance
bottleneck.

(Personally, I wouldn't try to use bitwise operations on signed
integers; I've never bothered to learn how they behave. If I ever
need to know, I'll look it up.)

Also, the OP didn't say he's working with integers.

Just write the code as clearly as possible, such as:

(a >= 0 && b >= 0) || (a < 0 && b < 0)

or even

(a >= 0) == (b >= 0)

I agree with everything you wrote about obscurity. I'll just make the
observation that compilers are notoriously bad at certain types of
comparisons.

A plain vanilla comparison (a < b) is generally done well.

However, with bitfields in particular, I've seen some really bad code. For
example, on the compiler I'm using presently (with bitfields of size 1), the
comparison:

(x.bf1 == x.bf2)

results in a huge bulk of code as the bitfields are converted into integers
and then compared.

I've actually found it is cheaper to write:

((x.bf1 && x.bf2) || (!x.bf1 && !x.bf2))

I do agree with you in principle about micro-optimization. You are right.
 
G

Gordon Burditt

And if either of the values may be a floating-point number, you
I believe the standards commitee has found that there are no
implementations extant where insistance on all bits zero will fail
to simulate 0.0, and thus plan to allow that in the future. NULL
is another matter, but usually works. Document any such usage as
non-portable.

On the other hand, many implementations (including all the IEEE
floating-point ones) have at least two distinct representations of
zero, at least one of which isn't all-bits-zero (although the other
one probably is all-bits-zero).
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top