標準庫函數(如 std::round、printf("%.2f"))均採用四捨五入規則。對於負數,直接截斷(向零取整)與向下取整(floor)結果不同:
-1.2345 → 截斷:-1.23,四捨五入:-1.23-1.2365 → 截斷:-1.23,四捨五入:-1.24-1.6543 → 截斷:-1.65,四捨五入:-1.65#include <iostream>
#include <cmath>
double truncateTwoDecimals(double n) {
bool isNegative = n < 0;
if (isNegative) n = -n; // 轉為正數處理
n = std::trunc(n * 100.0) / 100.0; // 乘100 → 截斷小數 → 除100
return isNegative ? -n : n; // 恢復符號
}
// C++11 起可用 std::trunc,舊標準可用 (int)(n * 100.0) / 100.0
// 注意:int 轉換屬於向零截斷行為,符合需求
#include <iostream>
#include <cmath>
#include <iomanip>
double truncateTwoDecimals(double n) {
bool sign = n < 0;
if (sign) n = -n;
n = std::trunc(n * 100.0) / 100.0;
return sign ? -n : n;
}
int main() {
double testCases[] = {-1.2345, -1.2365, -1.6543, 1.2345, 1.2365, 1.6543, -0.001, -0.009};
std::cout << std::fixed << std::setprecision(4);
std::cout << "原始值\t\t截斷結果\t四捨五入\n";
std::cout << "------------------------------------------\n";
for (double val : testCases) {
double truncated = truncateTwoDecimals(val);
double rounded = std::round(val * 100.0) / 100.0;
std::cout << val << "\t\t" << truncated << "\t\t" << rounded << "\n";
}
return 0;
}
原始值 截斷結果 四捨五入
------------------------------------------
-1.2345 -1.2300 -1.2300
-1.2365 -1.2300 -1.2400
-1.6543 -1.6500 -1.6500
1.2345 1.2300 1.2300
1.2365 1.2300 1.2400
1.6543 1.6500 1.6500
-0.0010 -0.0000 -0.0000
-0.0090 -0.0000 -0.0100
#include <string>
#include <sstream>
std::string truncateTwoDecimalsStr(double n) {
std::ostringstream oss;
oss << std::fixed << std::setprecision(10) << n; // 高精度轉字串
std::string s = oss.str();
size_t dotPos = s.find('.');
if (dotPos != std::string::npos && dotPos + 3 < s.length()) {
s = s.substr(0, dotPos + 3); // 保留小數點後兩位
}
// 移除末尾多餘的零(可選)
// s.erase(s.find_last_not_of('0') + 1, std::string::npos);
// if (s.back() == '.') s.pop_back();
return s;
}
std::format 簡化格式化輸出負數截斷保留兩位小數的核心是「取絕對值 → 乘100 → 向零取整 → 除100 → 恢復符號」。std::trunc 或 (int) 強制轉換均可實現向零截斷,配合符號處理即可正確應對正負數場景。