浮點數(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;
}