我收到关于可能的数据丢失的良性警告
警告C4244:'参数':从'const int'转换为'float',可能会丢失数据
问题
我记得浮动的精度比int大。那么,如果我从较小的数据类型(int)转换为更大的数据类型(浮动),数据将如何丢失?
答案 0 :(得分:14)
因为float
数字不准确。即使int
的最大值高得多,您也无法将float
可以容纳的所有值表示为float
。
例如,运行这个简单的程序:
#include <stdio.h>
int main()
{
for(int i = 0; i < 2147483647; i++)
{
float value = i;
int ivalue = value;
if(i != ivalue)
printf("Integer %d is represented as %d in a float\n", i, ivalue);
}
}
您很快就会发现千位数十亿的整数无法表示为float
。例如,范围16,777,219和16,777,221之间的所有整数表示为16,777,220。
再次编辑在上面运行该程序表示 2,071,986,175 正整数无法准确表示为float
s。这使得大约只有1亿正整数适合float
。这意味着当您将它放入浮动时, 21 中只有一个整数是正确的。
我希望负整数的数字相同。
答案 1 :(得分:6)
在大多数架构上int
和float
的大小相同,因为它们具有相同的位数。但是,在浮点数中,这些位在指数和尾数之间分开,这意味着浮点数中的精度位数实际上比int小。但是,这对于较大的整数来说可能只是一个问题。
在int
为32位的系统上,double
通常为64位,因此可以精确地表示任何int。
答案 2 :(得分:3)
两种类型都由4个字节(32位)组成。 其中只有一个允许一个分数(浮动)。
以浮动为例;
34.156
(整数)。(分数)
现在使用你的逻辑; 如果其中一个必须保存分数信息(毕竟它应该代表一个数字)那么这意味着它对整数部分的位数较少。
因此,float可以表示一个小于int类型能力的最大整数。
更具体地说,“int”使用32位来表示整数(最大无符号整数4,294,967,296)。 “float”使用23位(最大无符号整数8,388,608)。
这就是为什么当你从int转换为float时你可能会丢失数据。
实施例: int = 1,158,354,125
您无法将此号码存储在“浮动”中。
更多信息:
http://en.wikipedia.org/wiki/Single_precision_floating-point_format
答案 3 :(得分:1)
精确无关紧要。 int的精度为1,而典型浮点(IEEE 754单精度)的精度约为5.96e-8。重要的是两种格式可以表示的数字集。如果有数字,int可以准确表示浮点数不能,那么可能会丢失数据。
这些天浮点数和整数通常都是32位,但这并不能保证。假设你的机器就是这种情况,那么必须有float值无法准确表示的int值,因为显然有一些int无法准确表示的float值。如果两种格式有效地使用相同的位数,则一种格式的范围不能是另一种格式的适当超集。
32位int有效地具有31位,用于编码该数字的绝对值。 IEEE 754浮点实际上只有24位代码用于尾数(一个隐式)。
答案 4 :(得分:0)
float
通常采用标准IEEE单精度格式。这意味着float
中只有24位精度,而int
可能是32位。因此,如果您的int
包含绝对值不能容纳24位的数字,则可能会将其四舍五入到最接近的可表示数字。
答案 5 :(得分:0)
答案 6 :(得分:0)
事实是float和int都使用32位表示。整数值使用全部32位,因此它可以容纳从-2 31 到2 31 -1的数字。但是,浮点数使用1位作为符号(包括-0.0f),使用8位作为指数。装置32-9 =剩余23位用于尾数。但是,浮点数假定如果尾数和指数不为零,那么尾数从1开始。因此,您或多或少有24位用于整数,而不是32位。但是,因为它可以移位,所以它可以容纳更多比2 24 整数。
A floating point uses a Sign, an eXponent, and a Mantissa
S X X X X X X X X M M M M M M M M M M M M M M M M M M M M M M M
An integer has a Sign, and a Mantissa
S M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M
所以,一个整数,如:
1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
适合浮动,因为它可以移位:
1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
| | |
| +---------+ +---------+
| | |
v v v
S X X X X X X X X M M M M M M M M M M M M M M M M M M M M M M M
1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0
我没有向你展示eXponent,因为我经常在计算它时犯了一个错误,但它应该是5(或-5?),因为我移动了5位(但是你必须加或减128) ...)。这清楚地表明,如果你必须移位5位,你将失去5位低位。
所以这个其他整数可以转换为丢失2位的浮点数(即当你转换回整数时,最后两位(11)被设置为零(00),因为它们没有保存在浮动):
1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1
| | | | | | | |
| +---------+ +---------+ +-+-+-+-+--> all lost
| | |
v v v
S X X X X X X X X M M M M M M M M M M M M M M M M M M M M M M M
1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0
非常简单的东西。
重要说明:是的,整数中的前1是符号,然后下一个1不会复制到尾数中,假定它是1,因此不需要。