First Commit

This commit is contained in:
xiaolinquan committed 2026-11-06 01:04:35 +08:00
commit 3796ec5cd2
146 files changed
+4825

No files matched your search

+94
View File
@@ -0,0 +1,94 @@
#include "conversion.h"
#include <QRegularExpression>
#include <cmath>
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;
}
}