1
我寫了一個相對簡單的代碼,將雙精度轉換爲有理數。代碼起作用,並且保證爲給定的double找到最小的有理數;然而,它在一月份比糖漿慢。我花了一天的時間嘗試各種方法來改善它無濟於事。有關如何加速它的任何想法?實際的算法在while循環中,僅有8行。加速翻倍理性數字轉換
#include <iostream>
#include <iomanip>
using namespace std;
void rationalize(double number) {
bool isNegative = false;
if (number == 0.0) {
cout << number << ": " << "0/1" << endl;
return;
}
if (abs(number) < (1.0/(double) LONG_MAX)) {
cout << number << " is to small " << endl;
return;
}
if (abs(number) > (double)LONG_MAX) {
cout << number << " is to big " << endl;
return;
}
if (number < 0) {
isNegative = true;
number *= -1;
}
long numerator = 1; // at this point, both numerator
long denominator = 1; // and denominator must be >= 1
double diff = 1.0 - number;
//while ((abs(diff) > DBL_EPSILON) && (numerator > 0) && (denominator > 0)) {
while ((abs(diff) > FLT_MIN) && (numerator > 0) && (denominator > 0)) {
if (diff > 0) {
denominator++;
} else {
numerator++;
}
diff = ((double) numerator/(double) denominator) - number;
} // end while
if ((numerator <= 0) || (denominator <= 0)) {
cout << "\nInteger overflow!" << endl;
cout << "diff: " << diff << ", numerator: " << numerator << " denominator: " << denominator << endl;
return;
}
if (diff == 0.0) {
cout << " Exact result: ";
cout << (isNegative ? -numerator : numerator) << "/" << denominator << endl;
} else if (diff <= FLT_MIN) {
cout << "Approximate result: ";
cout << (isNegative ? -numerator : numerator) << "/" << denominator << endl;
} else {
cout << "You've got bugs... :(" << endl;
cout << "diff: " << diff << ", num:" << numerator << ", den: " << denominator << endl;
}
}
int main(void) {
cout << "\nworking on: (31/65537) " << endl;
rationalize(4.7301524329767917359659429024826e-4);
cout << "\nworking on: (262139/2^31-1) " << endl;
rationalize(1.220679842504057959888157416083e-4);
cout << "\nworking on: (-262147/2^31-1) " << endl;
rationalize(-1.2207170954070599262635502620896e-4);
cout << "\nworking on: (1048573/2147483647)" << endl;
rationalize(4.882798532435111018100339462096e-4);
cout << "\nworking on: (-1048583/2147483647)" << endl;
rationalize(-4.8828450985638634760695805196043e-4);
getchar();
return EXIT_SUCCESS;
}
我想你希望在這裏使用GCD。 –
你不能在'double'中存儲最合理的值,因此你的解決方案將無法工作。所有雙打實際上都是有理數值形式'有效數/ 2 ^( - exp)' –
a)我想將雙數轉換爲有理數而不是其他方式,b)根據我的代碼,範圍限制爲:[1/(2^31 - 1).. 2^31 - 1] c)IEEE-754雙打僅表示有限數量的雙打d)它不一定必須是*精確*:if(diff <= FLT_MIN ) – JSz