C++ 将无符号整型转换为浮点型时出错
背景:我在记录中有一些元素,其中一些元素可以是float、unsigned int或unsigned long。因此,我想使用float作为一个公共值,从读取这些元素的函数返回 然而,我在将无符号int转换为float时看到了这个奇怪的错误。打印值时,它会发生更改。我怎样才能避免呢?我不应该从这个函数返回float吗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
#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