0

I've been given a couple of numbers from tests that were stored as unsigned ints used by Contiki, implemented in C (i.e., unsigned int) and were basically constantly added to with positive numbers.

They are now negative, so I'm assuming they wrapped around. Somebody asked me to get the 'actual' supposed value of the integers.

All integers are below 32768, so I'm assuming it wraps around at 2^15. A lot of the integers are close to -32768, so I'm assuming it goes from 32768 to -32768.

So basically, if I've gotten an integer like -23000, its actual supposed value (in my case) is (32768 + (32768 - 23000)) = 42536?

Is this correct?

Edit:

To be very clear, I'm talking about uipstats_t types as defined in contiki. Like so:

struct uip_stats {


 struct {
    uip_stats_t recv;     /**< Number of received packets at the IP
                 layer. */
    uip_stats_t sent;     /**< Number of sent packets at the IP
                 layer. */
    uip_stats_t forwarded;/**< Number of forwarded packets at the IP
                 layer. */
    uip_stats_t drop;     /**< Number of dropped packets at the IP
                 layer. */
    uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong
                 IP version or header length. */
    uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
                 IP length, high byte. */
    uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
                 IP length, low byte. */
    uip_stats_t fragerr;  /**< Number of packets dropped because they
                 were IP fragments. */
    uip_stats_t chkerr;   /**< Number of packets dropped due to IP
                 checksum errors. */
    uip_stats_t protoerr; /**< Number of packets dropped because they
                 were neither ICMP, UDP nor TCP. */
  } ip; 

They are defined for my platform as:

typedef unsigned int uip_stats_t;

and they have been logged and presented to me as follows:

    PRINTA("UIP STATS. recv %d sent %d drp %d\n",
        uip_stat.ip.recv,
        uip_stat.ip.sent,
        uip_stat.ip.drop);

I've been numbers as printed by the above code.

  • 1
    "They are now negative" - what does that *mean*? Do you mean *you* loaded them into `int16_t` variables or something similar? How exactly did values stored as `unsigned int` become "negative" ? (hint: code speaks loudly). – WhozCraig May 02 '15 at 19:46
  • `unsigned int`s should never wrap around to a negative number. See http://stackoverflow.com/q/18195715/3488231 – user12205 May 02 '15 at 19:48
  • I'm unclear, apologies. Hopefully my edit will make everything clear. I suspect there may be issues to the printing code. –  May 02 '15 at 19:54
  • In your output statement, try using `%u` instead of `%d`. – user12205 May 02 '15 at 19:54
  • 1
    Your problem is all in `printf()` - `%d` is for regular `int`s, not `unsigned int`s. Use `%u` instead. – Crowman May 02 '15 at 19:54
  • Unfortunately, not my print outs. But given that is printed as %d, the actual value (as would be printed by %u) is as I described, right? –  May 02 '15 at 20:02

1 Answers1

1

In your output PRINTA() statement, you used %d as the format specifier.

Assuming it is some wrapper around the printf() family, %d is used for signed integers(*) only; to output unsigned integers(*), you should use the %u specifier instead.

(*): In this context, I mean variables with types int and unsigned int (or equivalent). For integer types with other sizes, the output specifier is different.

To demonstrate this, consider the following example:

int main() {
    int a;
    unsigned int b;
    a = -1;
    b = *(unsigned int *)&a;
    printf("%d %u\n", b, b);
    return 0;
}

On my platform this outputs:

-1 4294967295

To further understand this, you may wish to have a read about Two's complement.

user12205
  • 2,684
  • 1
  • 20
  • 40
  • Strictly speaking, `%d` is for `int` only, including equivalent types `typeddef`ed to `int`, so is `%u` for `unsigned int` and equivalents. – user3528438 May 02 '15 at 20:02
  • Unfortunately, not my print outs. But given that is printed as %d, the actual value (as would be printed by %u) is as I described, right? –  May 02 '15 at 20:02
  • @SvenAkkermans Not necessarily. If the unsigned int has the most significant bit set, `printf()` will output it as a negative number with `%d` but positive with `%u`. – user12205 May 02 '15 at 20:04
  • @SvenAkkermans I have edited my answer to demonstrate my previous comment. – user12205 May 02 '15 at 20:08