基本上如果是我我會盡量少用浮點數這個宣告
先目測看下面程式片段的執行結果吧!
x=(float)3/7;
y=(float)1/7;
printf("%f\n",(float)x/y);
if(x/y==3.000000)
printf("(3/7)/(1/7)==3.000000\n");
else
printf("(3/7)/(1/7)!=3.000000\n");
非常可惜你應該猜錯了
正確答案如下
3.000000
(3/7)/(1/7)!=3.000000
搞什麼鬼阿?!
為什麼出現這麼矛盾的結果呢?
其實在電腦中所有的資訊都是由二進位所紀錄成的
所以有的數並不能準確的被儲存
像(0.3)10=(0.010011001100...)2
是一個循環小數
所以電腦會儲存前面部分的位數
像0.0100110011=2.99805大約等於3這樣
所以上面的分數除法把這個誤差給挖大了,雖然輸出看起來還是3,實際上已經差很遠了...
那要怎麼突破呢?
其實可以把它儲存成分數
X_S是X的分子
X_M是X的分母
Y_S是Y的分子
Y_M是Y的分母
再運用分子分母通分後相除,自然就能算出十分精準的數了。
x_s=3;
x_m=7;
y_s=1;
y_m=7;
printf("%f\n",(float) ( (x_s*y_m) / (x_m*y_s) ) );
if((float) ( (x_s*y_m) / (x_m*y_s) ) ==3.000000)
printf("(3/7)/(1/7)==3.000000\n");
else
printf("(3/7)/(1/7)!=3.000000\n");
3.000000
(3/7)/(1/7)==3.000000
其實用結構可以寫的更乾脆
用這個方法可以幾近表示成幾近所有的有理數
夠酷吧!!
沒有留言:
張貼留言