Integer promotion

S

Spoon

Consider the following program:

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
uint32_t a = strtoul(argv[1], 0, 0);
uint32_t b = strtoul(argv[2], 0, 0);
double d = a-b;
printf("%f\n", d);
return 0;
}

$ ./a.out 5 6
4294967295.000000

This is what I expected.
Since a-b would be negative, the result is a-b+2^32.

However, if I replace uint32_t with uint16_t:

$ ./a.out 5 6
-1.000000

I expected 65535 (-1+2^16).

I suppose I'm forgetting some integer promotion rule?

Is the simple fix just to write:

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
uint16_t a = strtoul(argv[1], 0, 0);
uint16_t b = strtoul(argv[2], 0, 0);
uint16_t diff = a-b;
double d = diff;
printf("%f\n", d);
return 0;
}

Regards.
 
J

Jack Klein

Consider the following program:

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
uint32_t a = strtoul(argv[1], 0, 0);
uint32_t b = strtoul(argv[2], 0, 0);
double d = a-b;
printf("%f\n", d);
return 0;
}

$ ./a.out 5 6
4294967295.000000

This is what I expected.
Since a-b would be negative, the result is a-b+2^32.

However, if I replace uint32_t with uint16_t:

$ ./a.out 5 6
-1.000000

I expected 65535 (-1+2^16).

Why? Assuming that int has more than 16 bits on your platform, the
values of both 'a' and 'b' are promoted to signed int before the
addition, and the signed int result is then converted to double and
assigned to 'd'.
I suppose I'm forgetting some integer promotion rule?

Is the simple fix just to write:

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
uint16_t a = strtoul(argv[1], 0, 0);
uint16_t b = strtoul(argv[2], 0, 0);
uint16_t diff = a-b;
double d = diff;
printf("%f\n", d);
return 0;
}

Regards.

Integer types narrower (of lesser rank) than int are always promoted
to int or unsigned int when used as operands of expressions. The
rules for this promotion from unsigned types of lesser rank than int
are:

-- if signed int can hold all the possible values of the lesser rank
unsigned type, the value is promoted to signed int.

-- if signed int cannot hold all the possible values of the lesser
rank unsigned type, the value is promoted to unsigned int.

So if you build and execute this program on a platform where int has
16 bits, the values in 'a' and 'b' would promote to unsigned int and
produced the result you expected. Since int on your platform has more
than 16 bits, the values in 'a' and 'b' promoted to signed int and
produced the result you saw.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
¬

¬a\\/b

Consider the following program:

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
uint32_t a = strtoul(argv[1], 0, 0);
uint32_t b = strtoul(argv[2], 0, 0);
double d = a-b;
^^^^^^^^^^^^^^^^^^^^^^^

double d = (double)a-b;
 

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,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top