日常開發中(對話框、數據庫、金融、短信等)頻繁需要將浮點數按指定小數位格式化為字符串,如 123.45678 → "123.45"。標準庫無直接支持,需自行實現。
<sstream> 庫(ostringstream)string do_fraction(long double value, int decplaces = 3);
// decplaces 包含小數點,故保留 2 位小數傳 3
stringstream 默認精度 6 位(總位數,非小數位),大數會科學計數法輸出。須設為最大精度:
int prec = numeric_limits<long double>::digits10; // 18
ostringstream out;
out.precision(prec);
out << value;
string str = out.str();
const char DECIMAL_POINT = '.'; // 歐洲用 ','
size_t n = str.find(DECIMAL_POINT);
if (n != string::npos && str.size() > n + decplaces) {
str[n + decplaces] = '\0'; // 覆蓋多餘位
}
利用 c_str() 遇 \0 截斷特性,配合 swap 縮減字符串:
str.swap(string(str.c_str())); // 老編譯器可用 str = string(str.c_str());
string do_fraction(long double value, int decplaces = 3) {
ostringstream out;
out.precision(numeric_limits<long double>::digits10);
out << value;
string str = out.str();
size_t n = str.find('.');
if (n != string::npos && str.size() > n + decplaces) {
str[n + decplaces] = '\0';
}
str.swap(string(str.c_str()));
return str;
}
若不想拷貝返回,可改引用傳遞:void do_fraction(long double, string&, int)。但返回值允許鏈式調用:cout << do_fraction(123456789.69999) << '\t' << do_fraction(12.011); 輸出 123456789.69 12.01。
通過 <sstream> 高精度轉字符串 + find 定位 + \0 截斷 + swap 清理,實現高效、彈性、無科學計數法干擾的浮點數格式化。