C++ 将无符号整型转换为浮点型时出错

C++ 将无符号整型转换为浮点型时出错,c++,floating-point,type-conversion,C++,Floating Point,Type Conversion,背景:我在记录中有一些元素,其中一些元素可以是float、unsigned int或unsigned long。因此,我想使用float作为一个公共值,从读取这些元素的函数返回 然而,我在将无符号int转换为float时看到了这个奇怪的错误。打印值时,它会发生更改。我怎样才能避免呢?我不应该从这个函数返回float吗 #include <iostream> #include <limits> using namespace std; int main() { unsi

背景:我在记录中有一些元素,其中一些元素可以是float、unsigned int或unsigned long。因此,我想使用float作为一个公共值,从读取这些元素的函数返回

然而,我在将无符号int转换为float时看到了这个奇怪的错误。打印值时,它会发生更改。我怎样才能避免呢?我不应该从这个函数返回float吗

#include <iostream>
#include <limits>
using namespace std;
int main()
{
  unsigned int  myU = numeric_limits<unsigned int>::max();
  cout<<" myU is "<<myU<<'\n'; //correct
  float myF = (float) myU;
  cout<<" back To Long "<<(unsigned long long ) myF<<'\n'; //error?
  cout<<" back To unsigned int "<<(unsigned int ) myF<<'\n'; //error?
  cout<<" to Float Without Fixed "<<(float) myU<<'\n';//not clear, so have to use fixed
  cout<<" to Float With Fixed "<<fixed<<(float) myU<<'\n';//error?
  cout<<" difference "<<myF-myU<<'\n'; //error?
  cout<<" myU+32 "<<myU+32<<'\n'; //-1+32=31 ==> understandable
}

你看到的主要问题是,a只能提供其分数部分的有限精度,这当然是自然的,因为它只能保存这么多信息


现在,当您从
无符号整数
转换为
浮点
时,您使用的数字太长,无法放入小数部分。现在一些精度已经丢失,您可以将其转换回整数格式,这可能会有所不同。对于
unsigned long long
,结果只会大一个,但是在转换为
unsigned int
时,会出现溢出。

浮点(32位IEEE 754)中的数字
4294967295
表示如下:

0       10011111      00000000000000000000000
sign    exponent      mantissa
(+1)    (2^32)        (1.0)
将其转换回整数(在本例中为long)的规则是:

结果将是
4294967296
,它的大小适合您填充
long
,但太大,不适合
unsigned int
,因此对于
unsigned int
转换,您将得到
0


请注意,问题在于使用浮点表示大数的局限性,例如
4294967295
4294967200
当它们存储为浮点时,它们都表示相同的位。

32位的精度不足以存储32位无符号整数(更糟糕的是长整数)的精确值因为有效位精度只有24位。请尝试改用double,但不能用于长整型。注意:“返回到无符号整型”行会导致未定义的行为,因为该值超出了范围range@M.M谢谢你的提示,我更正了,是的,4294967200和4294967295之间的数字不具有代表性OK。我想说的一点是,4294967295不是这样表示的(事实上它根本不可表示);如果您试图表示该数字,则可能会出现您所显示的表示形式。
0       10011111      00000000000000000000000
sign    exponent      mantissa
(+1)    (2^32)        (1.0)
sign * (2^exponent) * mantissa