user4346741
user4346741

Reputation:

Unsigned wrapped around Integer to the 'actual' value C

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.

Upvotes: 0

Views: 170

Answers (1)

user12205
user12205

Reputation: 2702

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.

Upvotes: 1

Related Questions