問題描述:
如何將浮點數(小數)轉換為分數的形式,這樣可以更精確的表達出浮點數的值。
問題分析:
小數可以分為兩種,有限小數和無限迴圈小數。
有限小數的處理相對簡單:
只要把它乘以10的n次方,轉換為整數,再和10的n次方都除以它們的最大公約數即可。
例如:0.25 把它乘以 10的2次方 變成25, 25/100 分子分母除以最大公約數25變成1/4即可。
無限迴圈小數的處理要複雜一些:
書中使用了乙個有趣的計算方法,它把無限迴圈小數分為一小數部分和乙個迴圈部分 例如: x=0.a1a2...am(b1b2...bn)
這裡a是小數部分,b是迴圈部分。
1) x先乘以10的m次方,把小數部分變為整數 x*10^m ==> a1a2...am + 0
.b1b2...bn(b1b2...bn)
x = (a1a2...am + 0.b1b2...bn(b1b2...bn))/(10^m)
2) 假設 y = 0.b1b2...bn(b1b2...bn),那麼y可以轉換為 y*10^n = b1b2...bn + 0.b1b2...bn(b1b2...bn)
y*10^n = b1b2...bn +
y ==> y = b1b2...bn/(10^n - 1)
3) 把y的部分代入x的等式中 x = (a1a2...am +
b1b2...bn/(10^n - 1))/(10^m)
x = (a1a2...am * (10^n - 1) + b1b2...bn) / ((10^n - 1)*10^m)
例如 0.3(3) = (3*9 + 3) / (9*10) = 30 / 90 = 1/3
例項程式:
程式中的缺陷,如果迴圈小數字數太多,會造成乘積超過int的範圍,造成計算錯誤。
#include using namespace std;
typedef struct _data
data_t;
unsigned long gcb(unsigned long a, unsigned long b)
r = b % a;
while(r != 0)
return a;
}void calc(data_t data)
temp = data._b;
while (temp != 0)
cout << "a->" << data._a << ":" << power_a << " b->" <> val;
return 0;
}
程式設計之美 2 6 精確表達浮點數
本題目內容如下 在計算機中,有時使用float或double來儲存小數是不能得到精確值的.如果你需要得到精確計算結果,最好是用分數形式來表示小數。有限小數或者無限迴圈小數都可以轉化為分數。eg 0.9 9 10 0.33 3 1 3 括號裡的數字表示的的是迴圈節 當然乙個小數可以用好幾種弄分數形式來...
程式設計之美 2 6 精確表達浮點數
題目 給乙個有限小數 或者 無限迴圈小數,用分母最小的方式用分數精確的表達這個數字。括號中表示迴圈部分,如 0.3 0.3 3 0.3 0 思路 我一看,傻眼了,想了兩下不想想了,就在網上找迴圈小數轉分數,結果居然是小學奧賽題!我鬱悶的很啊.拿 1.2 34 來舉例子吧 1.2 34 10 12.3...
程式設計之美 2 6 精確表達浮點數
1.簡述 簡單的說就是將有限迴圈小數和無限迴圈小數轉化為分數形式。比如 0.9 9 10 0.333 3 1 3,其中括號表示迴圈節。2.思路 書上的方法就是分情況討論。首先是有限迴圈小數,比如123.456,整數部分123不用說了,主要是小數部分0.456,直接轉化為456 1000,然後消去最大...