简体   繁体   English

将unsigned [char,short,int,long]转换为double的结果不一致

[英]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? 为什么结果不一致,某些类型产生-10,而其他类型产生巨大价值?

The operand of a unary - operator is promoted ; 一元的操作-操作员晋升 ; types narrower than int are promoted to int or to unsigned int . int更窄的类型被提升为intunsigned 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 . 由于(signed) int可以包含可以由unsigned char表示的所有值,因此值(unsigned char)10将被提升为signed int10 Negating that gives you the (signed) int value -10 , which is then converted to double . 否定为您提供(签名) int-10 ,然后将其转换为double

An unsigned int is not "promoted" to int , because int can't hold all the values. unsigned int不会“提升”为int ,因为int不能保存所有值。 So the expression -e applies the unsigned int negation operator, which obviously cannot yield a negative value. 所以表达式-e应用unsigned int negation运算符,显然不能产生负值。 The result is UINT_MAX + 1 - 10 , which on your system is 4294967286 . 结果是UINT_MAX + 1 - 10 ,在您的系统上是4294967286 Converting to double yields the value you see. 转换为double产生您看到的值。

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 ). 同样, unsigned long提升unsigned long ,因此-f产生ULONG_MAX + 1 - 10 ,当转换为double产生18446744073709551606 (2 64 -10)(显然你的系统有64位longunsigned long )。 Converting that value to double loses some precision, yielding the value you see. 将该值转换为double会失去一些精度,从而产生您看到的值。

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. 除了促销规则之外,重要的是要记住C表达式的类型(几乎总是)不受其出现的上下文的影响。 -f yields a result of the same value and type regardless of what it's assigned to. -f产生相同值和类型的结果,而不管它分配给什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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