关于数据丢失的警告c ++ / c

时间:2010-04-17 14:39:54

标签: c++ c visual-c++

我收到关于可能的数据丢失的良性警告

  

警告C4244:'参数':从'const int'转换为'float',可能会丢失数据

问题

我记得浮动的精度比int大。那么,如果我从较小的数据类型(int)转换为更大的数据类型(浮动),数据将如何丢失?

7 个答案:

答案 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)

在大多数架构上intfloat的大小相同,因为它们具有相同的位数。但是,在浮点数中,这些位在指数和尾数之间分开,这意味着浮点数中的精度位数实际上比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

http://en.wikipedia.org/wiki/Integer_%28computer_science%29

答案 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)

我对这些问题的回答是阅读本文 - What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 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,因此不需要。