2009-06-05 35 views
1

我有三組數字,一個測量(在0-1範圍內)兩個錯誤(正數和負數,這些數字應該一致地顯示爲顯着數數字向上取整,相當於第一個非零數字中的任何一個數字正確格式化有錯誤的數字(C++)

如果測量結果爲1(即只有錯誤中的數字需要考慮),該要求會被跳過。 :

0.95637 (+0.00123, -0.02935) --> 0.96 +0.00 -0.03 
1.00000 (+0.0, -0.0979) --> 1.0 +0.0 -0.1 (note had to truncate due to -ve error rounding up at first significant digit) 

現在,獲取第一個非零數字很容易通過採取log10(num),但我有一個愚蠢的時刻試圖以乾淨的方式進行剝離和修圓工作。

所有數據類型都是雙打的,選擇的語言是C++。歡迎任何想法!

+0

是否有您的實現不使用庫調用的約束? – 2009-06-05 22:13:47

+0

這並不完全清楚。 Ehy在第一行有效數字的位數是2,第二位是1?換句話說,爲什麼在第一行+0.00123被格式化爲+0.00,但在第二行+0.0被格式化爲+0.0? – 2009-06-05 22:28:48

回答

2

我的C++是鏽跡斑斑,但不會下做到這一點:

std::string FormatNum(double measurement, double poserror, double negerror) 
{ 
    int precision = 1; // Precision to use if all numbers are zero 

    if (poserror > 0) 
    precision = ceil(-1 * log10(poserror)); 
    if (negerror < 0) 
    precision = min(precision, ceil(-1 * log10(abs(negerror)))); 

    // If you meant the first non-zero in any of the 3 numbers, uncomment this: 
    //if(measurement < 1) 
    // precision = min(precision, ceil(-1 * log10(measurement))); 

    stringstream ss; 
    ss.setf(ios::fixed, ios::floatfield); 
    ss.precision(precision); 
    ss << measurement << " +" << poserror << " " << negerror ; 
    return ss.str(); 
} 
1

也許是這樣的:

std::string FormatNum(double num) 
{ 
    int numToDisplay ((int)((num + 0.005) * 100.0)); 
    stringstream ss; 
    int digitsToDisplay(abs(numToDisplay) % 100); 
    ss << ((num > 0) ? '+' : '-') << (abs(numToDisplay)/100) << '.' << (digitsToDisplay/10) << (digitsToDisplay % 10); 
    return ss.str(); 
} 

    stringstream ss; 
    ss << FormatNum(0.95637) << ' ' << FormatNum(+0.00123) << ' ' << FormatNum(-0.02935); 
0

我不太清楚你如何是LOG10將有助於你得到的第一個非零數字,但假設它(因此你知道什麼是小數位你被四捨五入到),下面的函數將正確輪:

double round(double num, int decimalPlaces) 
{ 
    //given your example of .95637 being rounded to two decimal places 
    double decimalMultiplier = pow(10, decimalPlaces); // = 100 
    double roundedShiftedNum = num * decimalMultiplier + 0.5; // = 96.137 
    double insignificantDigits = (roundedShiftedNum - (int)roundedShiftedNum; // = 0.137 
    return (roundedShiftedNum - insignificantDigits)/decimalMultiplier; // = (96.137 - 0.137)/100 = 0.96 
} 

這可能不是最完美的解決方案,但我相信它的工作原理(還沒有嘗試過,雖然)

2

使用

cout.setf(ios::fixed, ios::floatfield); 
cout.precision(2); 

在輸出數字之前應該做你正在尋找的東西。

編輯:作爲一個例子

double a = 0.95637; 
double b = 0.00123; 
double c = -0.02935; 

cout.setf(ios::fixed, ios::floatfield); 
cout.precision(2); 
cout << a << endl; 
cout << b << endl; 
cout << c << endl; 

將輸出:

0.96 
0.00 
-0.03 

進一步編輯:你會明顯地有調整精度,以符合您顯著數字。

0

這是由Shane Powell提供的版本中的變更。

std::string FormatNum(double num, int decimals) 
{ 
    stringstream ss; 
    if (num >= 0.0) 
     ss << '+'; 
    ss << setiosflags(ios::fixed) << setprecision(decimals) << num; 
    return ss.str(); 
}