c语言为什么警告说从“int”转换到“float”,可能丢失数据
#include<time.h>#include<stdio.h>#include<stdlib.h>#include<math.h>voidmain(){srand((...
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void main()
{
srand((unsigned)time(NULL));
for (int i=0; i<100; i++)
{
float a=rand()%11;//[0,10)
float b= a/10000;
printf("%f ", b);
}
getchar();
} 展开
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void main()
{
srand((unsigned)time(NULL));
for (int i=0; i<100; i++)
{
float a=rand()%11;//[0,10)
float b= a/10000;
printf("%f ", b);
}
getchar();
} 展开
7个回答
展开全部
int转float丢失数据说的是精度丢失。
在C语言中,int是整型变量,其代表的是准确值。而float是单精度浮点数,其本身是有精度限制的。也就是说,存在float变量中的数据,可能看起来是那个数,打印出来也是,但是实际存的是一个很接近但是并不准确的值。
比如int的值是1000,转成float之后,可能存的就是1000.0000000000001(仅做举例,实际上并不一定是这个值)。
这样int转换成float的时候,就出现了精度丢失。
对于越大的数,这种现象就越普遍。
在C语言中,int是整型变量,其代表的是准确值。而float是单精度浮点数,其本身是有精度限制的。也就是说,存在float变量中的数据,可能看起来是那个数,打印出来也是,但是实际存的是一个很接近但是并不准确的值。
比如int的值是1000,转成float之后,可能存的就是1000.0000000000001(仅做举例,实际上并不一定是这个值)。
这样int转换成float的时候,就出现了精度丢失。
对于越大的数,这种现象就越普遍。
展开全部
int采用2进制补码存储,大小32位。表示范围 -2^31 ~ 2^31-1.
单精度浮点数 存储机制为 (-1)^s * M * 2^E ,长度32位。
具体为 1个符号位, 8个指数位, 23 个有效位。
具体怎么计算的分三种情况,比较复杂就不说了。
当整数转换为浮点数时,首先位序列小数点移至最高位1的后面,如
15 = 1111 = 1.111 * 2^3,由此可知 s = 0, M = 1.111 = 1 + 1/2 + 1/4 + 1/8, E = 3.
换算后 可得15.0f 的二进制序列为
0 1000 0010 111 0000 0000 0000 0000 0000.
问题就在移动小数点,如果该整数的值大于2^24,即最高位1后面有24位甚至更多位,浮点数的有效位只会保存最高位1后面23位值,其余的都被rounding了。从而导致可能的精度丢失,比如
int a = pow(2,24)+1;
位序列为 0000 0001 0000 0000 0000 0000 0000 0001
移动小数点 =》 1.000 0000 0000 0000 0000 0000 × 2^24
最低位的1就被rounding了。
所以归根到底,当被rounding的位有1时,精度就变化了。
同时,double 为 1个符号位 , 11 个指数位, 52 个有效位,故 int 到double 不会丢失精度。
单精度浮点数 存储机制为 (-1)^s * M * 2^E ,长度32位。
具体为 1个符号位, 8个指数位, 23 个有效位。
具体怎么计算的分三种情况,比较复杂就不说了。
当整数转换为浮点数时,首先位序列小数点移至最高位1的后面,如
15 = 1111 = 1.111 * 2^3,由此可知 s = 0, M = 1.111 = 1 + 1/2 + 1/4 + 1/8, E = 3.
换算后 可得15.0f 的二进制序列为
0 1000 0010 111 0000 0000 0000 0000 0000.
问题就在移动小数点,如果该整数的值大于2^24,即最高位1后面有24位甚至更多位,浮点数的有效位只会保存最高位1后面23位值,其余的都被rounding了。从而导致可能的精度丢失,比如
int a = pow(2,24)+1;
位序列为 0000 0001 0000 0000 0000 0000 0000 0001
移动小数点 =》 1.000 0000 0000 0000 0000 0000 × 2^24
最低位的1就被rounding了。
所以归根到底,当被rounding的位有1时,精度就变化了。
同时,double 为 1个符号位 , 11 个指数位, 52 个有效位,故 int 到double 不会丢失精度。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
Widening primitive conversions(基本类型扩宽转换)。
以所占字节数为基准,单字节向多字节转换就是所谓的扩宽,比如1到2、2到4等。int到其他整数类型的转换、float到double是没有失真的,完全一致。但是整数到浮点数的转换虽然也是扩宽,但因为浮点数是用有效数字的方式进行表示的,转换的时候可能出现精度损失(float类型不能支持9位有效数字),如int i=1234567890;float pp = i - (float)i;pp不等于零。带符号int转换为其他整数类型的方法是对其数字的二位补码方式进行带符号扩展【这个me碰到问题的关键byte-》int】,char类型转换为int类型的方法是进行0扩展。提示:无论精度是否损失,扩宽转换都不能引发运行时错误。
以所占字节数为基准,单字节向多字节转换就是所谓的扩宽,比如1到2、2到4等。int到其他整数类型的转换、float到double是没有失真的,完全一致。但是整数到浮点数的转换虽然也是扩宽,但因为浮点数是用有效数字的方式进行表示的,转换的时候可能出现精度损失(float类型不能支持9位有效数字),如int i=1234567890;float pp = i - (float)i;pp不等于零。带符号int转换为其他整数类型的方法是对其数字的二位补码方式进行带符号扩展【这个me碰到问题的关键byte-》int】,char类型转换为int类型的方法是进行0扩展。提示:无论精度是否损失,扩宽转换都不能引发运行时错误。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
现代计算机采用的是IEEE754标准表示float型,此时能表示真值的只有24位二进制数,而int型是32位二进制数,可想而知这少的8位数float中就没法体现出来
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
int rand(void)
返回数据类型为int型
所以a=rand()%11也为int型
你却用float型当然它会那么提示
返回数据类型为int型
所以a=rand()%11也为int型
你却用float型当然它会那么提示
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询