在一般的PC平台下sizeof(double)=8,即它是8字节的,同时它是双精度浮点型,而float是单精度的。先把它们的基础知识复习一下,有些有点忘了。
%lf表示双精度,而%f表示单精度。
在没有认真学习之前的一种错误认识:认为64位的浮点数,有一部分用于表示整数部分,一部分用于表示小数部分。之所以是错误的是因为没有理解浮点所表示的意思:小数点的位置位置根据需要而浮动。即小数点的位置不是固定的。
该类型数据在内存中表示方式与整型的不同。它采用科学计数法的方式表示,即内存中由符号域、小数域和指数这三部分组成(但这三个域在内存中具体占多少位,并没有统一的规定,与不同平台有关)。如3.424在内存中的表示就类似如下:
+ | .3424 | 1 |
符号 | 小数域 | 指数域 |
/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
float a,b;
int d=123456789;
int d1;
a=123.456781e5;//12345678.9
d1=(int)a;
b=a+0.4;
printf("a=%f\n",a);
printf("b=%f\n",b);
printf("d=%d\n",d);
printf("d1=%d\n",d1);
}
注意:
float为32bit,而有效的
数字只有6-7个,因此
a=123.456789e5;//12345678.9,从7之后就是不确定的了。
b=a+0.4,也是先用double运算,再把double结果给float赋值。
double类型给float\int等类型赋值时可能发生精度损失问题。
a=12345678.000000
b=12345678.000000
d=123456789
d1=12345678
Press any key to continue
#include "stdio.h"
void main()
{
float a,b;
int d,d1;
a=3.56;// warning const double to float
b=(float)3.34;//这样就不警告了。
printf("a=%f,b=%f\n",a,b);//默认情况下,小数点6位
d=(int)a;//只取整数部分而不会四舍五入。
d1=(int)(b);//只取整数部分而不会四舍五入
printf("d=%d,d1=%d\n",d,d1);
printf("m.n的格式会四舍五入:%.1f,%.1f",a,b);
}
a=3.560000,b=3.340000
d=3,d1=3
m.n的格式会四舍五入:3.6,3.3Press any key to continue
a=1234567.45443; float a,b;
int d,d1;
char buf[14];
a=(float)3.56;
b=(float)3.34;//这样就不警告了。
sprintf(buf,"%.0f",a);
d=atoi(buf);
sprintf(buf,"%.0f",b);
d1=atoi(buf);
printf("d=%d,d1=%d\n",d,d1);
return 0;
d=4,d1=3
Press any key to continue
double df=3.4564233;
double df1=3.6564235;
int d;
printf("%lf\n",df);//double也默认只有6个小数
printf("%.7lf\n",df1);//可以完整输出。
d=(int)df1;//只取整数部分
df1=df1-d;
printf("%.7lf\n",df1);
3.456423
3.6564235
0.6564235
Press any key to continue
在一些算法或运算中可能要用到四舍五入、向上取整┌X┐、向下取整等操作.└X┘
其中ceil()函数是天花板的意思,即向上取整。floor为地板,即向下取整。
#include
double floor( double arg );
功能: 函数返回参数不大于arg的最大整数。
___________________________________
double ceil(double x);
功 能: 返回大于或者等于指定表达式的最小整数
如下完全二叉树中,若以1为根结点,则4,5这两个节点的双亲为[4/2] [5/2]都为向下取整。
int a=4;
int b=5;
int par;
par=(int)floor(a/2);
printf("a's parent index is:%d\n",par);
par=(int)floor(b/2);
printf("b's parent index is:%d\n",par);
a's parent index is:2
b's parent index is:2
Press any key to continue
对负数的处理,还是按数学上的大小进行的。即floor(-4.6)=-5. ceil(-3.4)=-3;
double a=4.67;
double b=-4.67;
double c=4.23;
double d=-4.23;
double a_floor=floor(a);
double b_floor=floor(b);
double c_floor=floor(c);
double d_floor=floor(d);
double a_ceil=ceil(a);
double b_ceil=ceil(b);
double c_ceil=ceil(c);
double d_ceil=ceil(d);
printf("a_floor=%lf,b_floor=%lf\n",a_floor,b_floor);
printf("c_floor=%lf,d_floor=%lf\n",c_floor,d_floor);
printf("a_ceil=%lf,b_ceil=%lf\n",a_ceil,b_ceil);
printf("c_ceil=%lf,d_ceil=%lf\n",c_ceil,d_ceil);
a_floor=4.000000,b_floor=-5.000000
c_floor=4.000000,d_floor=-5.000000
a_ceil=5.000000,b_ceil=-4.000000
c_ceil=5.000000,d_ceil=-4.000000
Press any key to continue
double a=179723554568;
int d=(int)a;
printf("a=%lf\n",a);
printf("d=%d\n",d);
return 0;
a=179723554568.000000
d=-665071864
Press any key to continue
2147483647=(0111 1111 1111 1111 1111 1111 1111 1111)
-2147483648= 1000 0000 0000 0000 0000 0000 0000 0000
double a=2147483647+1;
double a2=2147483648;//注意a2!=a
int d=(int)a;
int d2=(int)a2;
printf("a=%lf,a2=%lf\n",a,a2);
printf("d=%d,d2=%d\n",d,d2);
return 0;
a=-2147483648.000000,a2=2147483648.000000
d=-2147483648,d2=-2147483648
Press any key to continue
注意:a 并直接赋值,由于像1,2,344等整数,默认情况下是int类型的,而
2147483647能够用int类型存储,因此它还是按int类型计算的,但此时发生了溢出,从而它符号位变为1了,溢出后为最大的负数,再把这个负数赋值给double.
而
2147483648,则超出了int的范围,则上升为long int。1000 0000 0000 0000 0000 0000 0000 0000
0的二进制全为0,
-1的二进制全为1.
char c=128;
int dd=c;
printf("dd=%d\n",dd);
dd=-128
Press any key to continue
char c=352;//1 0110 0000
int dd=c;
printf("dd=%d\n",dd);
结果为它的低8位,为96 _________________________________________________________________________________________________________________________
在十进制中小数有些是无法完整用二进制表示的。它们只能用有限位来表示,从而在存储时可能就会有误差。十进制的小数采用乘2取整法进行计算,取掉整数部分后,剩下的小数继续乘以2,直到小数部分全为0.
如0.125变成二进制为
0.125*2=0.25 .....取整0
0.25*2=0.5 ........取整0
0.5*2= 1.0 ………取整1
0.0*2=0
所以0.125的二进制为0.001
double a=19.9;
int b=(int)(19.9*100);
printf("b=%d\n",b);
printf("a=%lf\n",a);
b=1989
a=19.900000
Press any key to continue
double a=19.9;
int b=(int)(19.9*10);
printf("b=%d\n",b);
printf("a=%.6lf\n",a);
return 0;
b=199
a=19.900000
Press any key to continue
VCwatch中观察到的为