"Daniel Fischer" <sp**@danny.homeunix.net> wrote in message
news:sl*****************@usenet.danny.homeunix.net ...
An @ 2004-07-14: I need to test the elements of an array of chars for non-negativity.
Note that plain char need not be signed.
I've read the following: "On most architectures testing for
non-negativity can be done several bytes at a time." Is this
possible with C as well?
I'd imagine you could map the sign bit of a couple of chars into a
different type in order to check for any of them being one, which
would mean one of the elements is negative.
However the machine independent solution does not gain anything
over a straight implementation, except if you're using a very
intelligent compiler, but relying on a specific compiler wouldn't
be independent anymore so...
A machine dependent solution, which I'm posting for the purely
academic reason of informing people what they shouldn't do, could
look similar to this:
if(*(unsigned short *)(a+i) & 0x8080)
You can easily confirm specifics and choose either coarse at your leisure. The only
difficulty is assuming the buffer to be scanned is suitably aligned for the longer type,
but that can be resolved with c/re/malloc().
#include <string.h>
#include <limits.h>
/*
// precondition: p is aligned for unsigned long
*/
int negative_present(const signed char *p, size_t n)
{
/*
// unpadded twos complement signed char?
*/
if (SCHAR_MAX - (unsigned) SCHAR_MIN == UCHAR_MAX)
{
unsigned long ul;
size_t i;
for (ul = -1, i = 1; i < sizeof ul; i++)
ul = ul >> (CHAR_BIT - 1) >> 1;
/*
// unpadded unsigned long?
*/
if (ul == UCHAR_MAX)
{
const unsigned long *ulp = (const unsigned long *) p;
signed char sc[sizeof ul];
for (i = 0; i < sizeof sc; i++)
sc[i] = SCHAR_MIN;
memcpy(&ul, sc, sizeof ul);
i = n / sizeof ul;
n -= i * sizeof ul;
while (i--)
if (*ulp++ & ul)
return 1;
p = (const signed char *) ulp;
}
}
while (n--)
if (*p++ < 0)
return 1;
return 0;
}
I'm not saying it should be done (or should be done this way), merely that it can be done.
--
Peter