1、怎么判断两个浮点数是否相等?
以下代码输出结果是什么
int main(int argc, char *argv[])
{
double a = 3.14;
float b = a;
if ((float)a == b)
{
printf("Xiyou");
}
if (a != b)
{
printf("LinuxGroup\n");
}
return 0;
}
//输出为:XiyouLinuxGroup
这里说明float a==float b,而double a !=float b,那是为什么呢?
首先
我们来了解float和double的存储方式,与整型不同
SEM型,float占32位4个字节,double占64位8个字节。
分别为符号位、指数、尾数
如:写出十进制数5.75的余127码(单精度)表示法。
a.符号为正,S=0。
b.十进制转二进制:5.75=(101.11)2进制
c.规范化:(101.11)(2进制)=(1.0111)*2^2(2的平方)
d.E=2+127=129=(10000001)2,M=0111。
M右边加19个0使之变成23位
表示如下
S E M
0 10000001 0111000000000000000000
存储在计算机中的数字是01000000101110000000000000000000
其次
- float的精度误差在1e-6;
所以要判断一个float型数:if(fabs(f) < 1e-6);
若满足,则相等- double精度误差在1e-15
要判断一个double型数:if(fabs(f) < 1e-15);
若满足,则相等
1e-6表示1乘以10的负6次方。
Math.abs(x)<1e-6其实相当于x==0
1e-6(也就是0.000001)叫做epslon,用来抵消浮点运算中因为误差造成的相等无法判断的情况。它通常是一个非常小的数字(具体多小要看你的运算误差)
比如说因为精度误差,用十进制举例,我们要算1/3+1/3+1/3==1(从数学上说,肯定相等),但是因为精度问题,等号左边算出来是0.3333333+0.3333333+0.3333333=0.9999999,
存在了误差,右边是1.0000000,那么如果直接用==,返回false,我们希望它被视作相等。那么就要两数相减取绝对值小于epslon的办法。
而float和double的精度误差要求不同,所以才会出现题目中的情况。
double的要求更高,所以当double a转为float能与b相等,但若用 (double )b和double a判断,则不能相等。
2、隐式类型转换
下面的代码输出的结果是什么呢?
int i;
int main(int argc, char *argv[])
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
//输出:>
这里int i为全局变量未赋值,初始化默认为0。i--后i变成-1。
sizeof(i)=4。此时不是-1与4的直接比较。
而是
sizeof结果为long unsigned int,是无符号型。
无符号型和有符号型比较,全都转为无符号型比较
而将-1转为无符号
1000000 00000000 00000000 00000001
此时开头的1不再表示符号
显然大于sizeof(i)=4。
(补码的用途?)
这里用到隐式类型转换的知识
进行算术运算(加、减、乘、除、取余以及符号运算)时,不同类型数据必须转换成同 一类型的数据才能运算,算术转换原则为:
整型提升:对于所有比int小的类型,包括char, signed char, unsigned char, short, unsigned short,首先会提升为int类型。
在进行运算时,以表达式中最长类型为主,将其他类型位据均转换成该类型,如:
(1)若运算数中有double型或float型,则其他类型数据均转换成double类型进行运算。
(2)若运算数中最长的类型为long型.则其他类型数均转换成long型数。
(3)若运算数中最长类型为int型,则char型也转换成int型进行运算。算术转换是在运算过程中自动完成的。
特别注意的是有符号和无符号之间的转换:
包含long与unsigned int,32位机器上都是4字节,所以均转换为unsigned long.
包含signed与unsigned int,signed会转换为unsigned。如果int恰好为负数,其结果为对unsigned取值个数求模的结果。比如将-1赋给8位的unsigned char,呢么结果就是255(-1对256取模后的值)。unsigned char取值范围0~255。
3、数据溢出
下面代码段将打印出多少个‘=’?
int main(int argc, char *argv[]) {
for (unsigned int i = 3; i >= 0; i--)
putchar('=');
}
//会不停地输出=
因为是unsigned int 型,当i=0时,再-1,变成4294967295
执行下面的代码段,会输出什么?
int main(int argc, char *argv[]) {
char ch = 255;
int d = 'a' + 1;
printf("%d %d", ch, d);
}
//输出结果:-1 98