testing for non-negativity

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • An

    #1

    testing for non-negativity

    Dear all,

    I need to test the elements of an array of chars for non-negativity.
    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? Is there a function to do so? First, I thought I
    could use the function memchr, but this is not specific for
    non-negativity and I'm not aware if it searches several bytes at a
    time. I hope someone can help me out....

    Kind regards and thanks in advance,

    An
  • Daniel Fischer

    #2
    Re: testing for non-negativity

    An @ 2004-07-14:[color=blue]
    > I need to test the elements of an array of chars for non-negativity.
    > 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?[/color]

    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)



    --
    Danny

    Comment

    • Peter Nilsson

      #3
      Re: testing for non-negativity

      "Daniel Fischer" <spam@danny.hom eunix.net> wrote in message
      news:slrncf9tst .egt.spam@usene t.danny.homeuni x.net...[color=blue]
      > An @ 2004-07-14:[color=green]
      > > I need to test the elements of an array of chars for non-negativity.[/color][/color]

      Note that plain char need not be signed.
      [color=blue][color=green]
      > > 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?[/color]
      >
      > 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)[/color]

      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_presen t(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


      Comment

      • Alex Fraser

        #4
        Re: testing for non-negativity

        "Peter Nilsson" <airia@acay.com .au> wrote in message
        news:40f51973@n ews.rivernet.co m.au...[color=blue]
        > "Daniel Fischer" <spam@danny.hom eunix.net> wrote in message
        > news:slrncf9tst .egt.spam@usene t.danny.homeuni x.net...[color=green]
        > > An @ 2004-07-14:[color=darkred]
        > > > I need to test the elements of an array of chars for non-negativity.[/color][/color]
        >
        > Note that plain char need not be signed.
        >[color=green][color=darkred]
        > > > 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?[/color]
        > >
        > > 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.[/color]
        >
        > 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().[/color]

        And better resolved by casting the pointer to a suitable integer type and
        checking its alignment. Since the method is platform-specific already, you
        might as well.

        Alex


        Comment

        • SM Ryan

          #5
          Re: testing for non-negativity

          One way is strcmp(newsgrou p,"comp.lang.c" )!=0

          an.commeine@stu dent.kuleuven.a c.be (An) wrote:
          # Dear all,
          #
          # I need to test the elements of an array of chars for non-negativity.
          # 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? Is there a function to do so? First, I thought I
          # could use the function memchr, but this is not specific for
          # non-negativity and I'm not aware if it searches several bytes at a
          # time. I hope someone can help me out....

          For an eight-bit byte twos complement, you can do
          (0x80&character )!=0
          Depending on alignment and integer sizes, you can do
          (0x808080808080 8080 & ((long long*)string)[i])!=0
          but this is a machine dependent solution. You can construct the
          0x80...80 constant and some of the other details by consulting
          sizeof and limits.h, but much of this remains machine dependent.

          --
          SM Ryan http://www.rawbw.com/~wyrmwif/
          Leave it to the Catholics to destroy existence.

          Comment

          • Jack Klein

            #6
            Re: testing for non-negativity

            On 14 Jul 2004 09:06:36 GMT, Daniel Fischer <spam@danny.hom eunix.net>
            wrote in comp.lang.c:
            [color=blue]
            > An @ 2004-07-14:[color=green]
            > > I need to test the elements of an array of chars for non-negativity.
            > > 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?[/color]
            >
            > 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)[/color]

            No, it is not machine dependent as far as C is concerned. It is
            undefined behavior to access objects with an lvalue of a different
            type, with the exception of accessing any object as an array of
            unsigned characters.

            It could be doubly undefined if a+i does not have the proper alignment
            for pointer to short.

            --
            Jack Klein
            Home: http://JK-Technology.Com
            FAQs for
            comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
            comp.lang.c++ http://www.parashift.com/c++-faq-lite/
            alt.comp.lang.l earn.c-c++

            Comment

            • Arthur J. O'Dwyer

              #7
              Re: testing for non-negativity


              On Wed, 14 Jul 2004, Jack Klein wrote:[color=blue]
              >
              > Daniel Fischer <spam@danny.hom eunix.net> wrote in comp.lang.c:[color=green]
              > > An @ 2004-07-14:[color=darkred]
              > > > I need to test the elements of an array of chars for non-negativity.
              > > > 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?[/color][/color][/color]
              <snip>[color=blue][color=green]
              > > 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)[/color]
              >
              > No, it is not machine dependent as far as C is concerned. It is
              > undefined behavior [...][/color]

              s/machine dependent/implementation dependent/ and his statement
              is correct. Note that
              "implementa tion-dependent" != "implementa tion-defined".

              -Arthur,
              from ghoulies and ghosties,
              and long-leggedy beasties,
              and language lawyers,

              Comment

              • Peter Nilsson

                #8
                Re: testing for non-negativity

                "Alex Fraser" <me@privacy.net > wrote in message news:2lkt1cFaip v9U1@uni-berlin.de...[color=blue]
                > "Peter Nilsson" <airia@acay.com .au> wrote in message
                > news:40f51973@n ews.rivernet.co m.au...[color=green]
                > > "Daniel Fischer" <spam@danny.hom eunix.net> wrote in message
                > > news:slrncf9tst .egt.spam@usene t.danny.homeuni x.net...[color=darkred]
                > > > An @ 2004-07-14:
                > > > > I need to test the elements of an array of chars for non-negativity.[/color]
                > >
                > > Note that plain char need not be signed.
                > >[color=darkred]
                > > > > 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.[/color]
                > >
                > > 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().[/color]
                >
                > And better resolved by casting the pointer to a suitable integer type and
                > checking its alignment. Since the method is platform-specific already, you
                > might as well.[/color]

                The routine I showed had the same optimisation but was not dependant on implementation, so
                I don't know why you're encouraging a line which is known to fail even for some twos
                complement machines.

                --
                Peter


                Comment

                Working...