简体   繁体   中英

Inconsistent results converting unsigned [char, short, int, long] to double

#include <stdio.h>

int main(int argc, char* argv[]) {
  unsigned char c = 10;
  unsigned short d = 10;
  unsigned int e = 10;
  unsigned long f = 10;
  double g = -c;
  double h = -d;
  double i = -e;
  double j = -f;
  printf("%d %lf\n", c, g);
  printf("%u %lf\n", d, h);
  printf("%u %lf\n", e, i);
  printf("%lu %lf\n", f, j);
}

gives as output

10 -10.000000
10 -10.000000
10 4294967286.000000
10 18446744073709551616.000000

Why are the results inconsistent, yielding -10 for some types and huge values for others?

The operand of a unary - operator is promoted ; types narrower than int are promoted to int or to unsigned int .

Since (signed) int can hold all the values that can be represented by an unsigned char , the value (unsigned char)10 is promoted to the signed int value 10 . Negating that gives you the (signed) int value -10 , which is then converted to double .

An unsigned int is not "promoted" to int , because int can't hold all the values. So the expression -e applies the unsigned int negation operator, which obviously cannot yield a negative value. The result is UINT_MAX + 1 - 10 , which on your system is 4294967286 . Converting to double yields the value you see.

Likewise, unsigned long is not promoted, so -f yields ULONG_MAX + 1 - 10 , which when converted to double yields 18446744073709551606 (2 64 -10) (apparently your system has 64-bit long and unsigned long ). Converting that value to double loses some precision, yielding the value you see.

Aside from the promotion rules, it's important to remember that the type of a C expression is (almost always) not affected by the context in which it appears. -f yields a result of the same value and type regardless of what it's assigned to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM