浮点数(float,double) 精度问题与宏定义(#define)
float(单精度) double(双精度)
字节 4 8
32位 64位
float类型所占用4个字节则会有32位,而在存储时,系统会将实型数据分成小数部分和指数二个部分来存储。由于小数也存在正负,最前面的单独一位来表示符号位。0表示正数。1表示负数。当然,这种时采取的时十进制保存数据。
我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点,24bit就能使float能精确到小数点后6位,同理:double类型数据能精确到小数点后15位。对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以指数部分的存储采用移位存储,存储的数据为元数据+127
在计算机中使用二进制的方法来存储数据:怎么表示呢?将十进制的数据转化为二进制存储
符号位+指数位+尾数位
Float 1 8 23
Double 1 11 52
符号位依然为 0表示正数 1表示负数
8.25,用二进制的科学计数法表示为:1000.1->1.0001*2^3
符号位为:0,表示为正,指数位为:3+127=130 ,位数部分为,故8.25的存储方式如下图所示:
精度问题:可以宏定义的方式来定义精度,
表示误差时,比如误差范围+-0.01,真实的距离X,合理的范围是Y
X-0.01<=Y&&Y<=X+0.01
宏定义(#define):我们在书写长长的程序时,当我们要对其中的一个数进行修改时,我们不可能把程序中的此数据逐个找出来进行修改,这时候,便有了宏定义(#define)
例:求ax^2+bx+c=0的解的情况
因为浮点数的表示会存在一些误差,所以应该用EPS来定义误差的范围,使得结果较为准确
#include <stdio.h>
#include <float.h>
#include <math.h>
#define EPS 0.000001
Void Fun(double a,double b,double c)
{
double x1;
double x2;
double d = b*b - 4*a*c;
//if(a == 0)//error
if(-EPS<=a &&a<EPS)//a==0
{
x1 = x2 = -c/b;
printf("x1=%f,x2=%f\n",x1,x2);
}
else //a != 0
{
if(-EPS<=d&& d<=EPS)//d==0
{
x1=x2=-b/(2*a);
printf("x1=%f,x2=%f\n",x1,x2);
}
else
{
if(d > EPS)
{
x1 =(-b+sqrt(d))/(2*a);
x2 =(-b-sqrt(d))/(2*a);
printf("x1=%f,x2=%f\n",x1,x2);
}
else //d<0
{
printf("无实根\n");
}
}
}
}
int main()
{
Fun(0,1,2);
Fun(1,2,1);
Fun(1,4,2);
Fun(1,1,1);
return 0;
}