#include "conversion.h" #include #include namespace Conversion { QStringList units(Category category) { if (category == Category::Temperature) return {QStringLiteral("摄氏度 °C"), QStringLiteral("华氏度 °F"), QStringLiteral("开尔文 K")}; return {QStringLiteral("毫米 mm"), QStringLiteral("厘米 cm"), QStringLiteral("米 m"), QStringLiteral("千米 km"), QStringLiteral("英寸 in"), QStringLiteral("英尺 ft")}; } Result convert(const QString &text, Category category, int from, int to) { Result result; const QString input = text.trimmed(); // 先检查完整输入,避免把“12abc”误当成有效数值。 static const QRegularExpression number( QStringLiteral("^[+-]?(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?$")); if (!number.match(input).hasMatch()) { result.error = QStringLiteral("请输入完整的数值,例如 25、-10.5 或 1e3;小数点使用英文句点。"); return result; } bool ok = false; const double value = input.toDouble(&ok); if (!ok || !std::isfinite(value)) { result.error = QStringLiteral("输入超出了可计算的数值范围,请减小数值。"); return result; } const QStringList names = units(category); if (from < 0 || to < 0 || from >= names.size() || to >= names.size()) { result.error = QStringLiteral("请选择有效的单位。"); return result; } if (category == Category::Temperature) { // 先统一为摄氏度,再换算为目标单位,避免为每对单位各写一套公式。 double celsius = value; QString first; if (from == 1) { celsius = (value - 32.0) / 1.8; first = QStringLiteral("先换成摄氏度:C = (F − 32) ÷ 1.8。"); } else if (from == 2) { celsius = value - 273.15; first = QStringLiteral("先换成摄氏度:C = K − 273.15。"); } else { first = QStringLiteral("输入已经是摄氏度,可直接作为中间值。"); } if (celsius < -273.15 - 1e-9) { result.error = QStringLiteral("温度不能低于绝对零度:−273.15 °C / −459.67 °F / 0 K。"); return result; } // 允许边界处的浮点舍入误差,避免把绝对零度误判为非法输入。 if (celsius < -273.15) celsius = -273.15; QString second; if (to == 1) { result.value = celsius * 1.8 + 32.0; second = QStringLiteral("再换成华氏度:F = C × 1.8 + 32。"); } else if (to == 2) { result.value = celsius + 273.15; second = QStringLiteral("再换成开尔文:K = C + 273.15。"); } else { result.value = celsius; second = QStringLiteral("目标是摄氏度,中间值就是结果。"); } result.explanation = first + QStringLiteral("\n") + second; } else { if (value < 0.0) { result.error = QStringLiteral("本工具换算的是长度,输入值不能为负数。"); return result; } const double metersPerUnit[] = {0.001, 0.01, 1.0, 1000.0, 0.0254, 0.3048}; result.value = value * (metersPerUnit[from] / metersPerUnit[to]); result.explanation = QStringLiteral("以米为统一单位:结果 = 输入值 × 源单位的米数 ÷ 目标单位的米数。\n" "本次计算:%1 × %2 ÷ %3。") .arg(input) .arg(metersPerUnit[from], 0, 'g', 12) .arg(metersPerUnit[to], 0, 'g', 12); } if (!std::isfinite(result.value)) { result.error = QStringLiteral("换算结果超出了可显示的数值范围。"); return result; } if (result.value == 0.0) result.value = 0.0; // 避免显示 -0。 result.ok = true; return result; } }