fix(resample): 重采样间隔/频率按真实值显示(次级单位与频率保留三位小数)
问题(用户实测 MF4-Record.MF4 / m_MOT_Current_DCom[0]): - 最小数据间隔真实值 0.003696631s,却被显示成 3ms 700us(us 部分被向上截取); - 对应频率真实值 270.516586589Hz,却被显示成 270.27Hz; - 最大数据间隔 0.016182614s 显示成 16ms 200us、频率显示成 61.7284Hz,同样不准。 根因(两个,同一个坑): 1. RoundIntervalForDisplay() 把间隔先舍入到 3 位有效数字(0.003696631 -> 0.0037), 次级单位因此变成 700us,真实尾数被抹掉; 2. 频率用舍入后的 3.70ms 换算得 270.27Hz,而输入框用原值得 270.517Hz,两处不一致。 修法(一律使用真实值,舍入只发生在输出文本的最后一步): - Utf8Util 新增 FormatDecimalFixed(value, decimals=3):固定小数位、保留尾随 0、 绝不出现科学计数法; - Utf8Util 新增 FormatSubUnit(value, maxDecimals):带小数才补到 3 位,整数不加小数点 (5.06s -> 5s 60ms,而不是 5s 60.000ms); - FormatDurationCompound 的两处次级单位(s+ms、ms/us/ns)改用它; - FormatFrequency 改为 FormatDecimalFixed(scaled, 3);若保留 3 位后变成 0.000 (超低频,如 1/3662s ≈ 0.27mHz)则退回 FormatDecimal,避免有意义的值显示成 0; - PlotViewInternal.hpp 删除 RoundIntervalForDisplay,FormatIntervalText 直接用真实值; - PlotViewPaint.cpp 的统计行尾缀与频率输入框都用真实 interval 换算。 修复后的显示: min interval 0.003696631s -> 3ms 696.631us frequency 1/0.003696631 -> 270.517 Hz max interval 0.016182614s -> 16ms 182.614us frequency 1/0.016182614 -> 61.795 Hz 同时撤销了此前两次仅修改 agent_mem.md 的提交(47b1213 / caa035a,内容为乱码且无有效信息), 并按正确编码重新整理本轮记忆章节。 面板仍为四行(最大间隔 / 最小间隔 / 重采样间隔 / 重采样频率),未改动任何 UI 布局。 make release 零 warning。
This commit is contained in:
1 parent
9fdbf49841
commit
c4300bd0e1
6 files changed
+260
-43
No files matched your search
@@ -1306,34 +1306,17 @@ namespace jdi
|
||||
return FormatValue(seconds) + L"s";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 把时间间隔四舍五入到 **3 位有效数字**(供「重采样」面板显示)。
|
||||
*
|
||||
* 计算出来的数据间隔常常带一长串浮点尾数(如 `5.0000158us`)。整串显示既没有意义,
|
||||
* 又会把面板撑得很宽(还要在后面追加「(频率)」尾缀,用户 2026-11-03 要求)。
|
||||
* 3 位有效数字足以区分相邻的采样间隔,且让显示稳定。
|
||||
*
|
||||
* @param [IN] seconds 时间间隔(秒)。
|
||||
* @return 舍入后的间隔;非法/非正输入原样返回。
|
||||
*/
|
||||
inline double RoundIntervalForDisplay(double seconds)
|
||||
{
|
||||
if (!std::isfinite(seconds) || seconds <= 0.0)
|
||||
{
|
||||
return seconds;
|
||||
}
|
||||
const double magnitude = std::floor(std::log10(seconds));
|
||||
const double scale = std::pow(10.0, 2.0 - magnitude);
|
||||
const double rounded = std::round(seconds * scale) / scale;
|
||||
return (rounded > 0.0) ? rounded : seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 时间间隔的显示文本(**不带** "Δt:" 前缀)。
|
||||
*
|
||||
* 「重采样」面板的「最大 / 最小数据间隔」两行用它:单位随间隔长短自适应
|
||||
*(`FormatDurationCompound`:1h 1min 2s / 5s 60ms / 120us …),
|
||||
* 且先舍入到 3 位有效数字(见 `RoundIntervalForDisplay`),**不出现科学计数法**。
|
||||
*(`FormatDurationCompound`:1h 1min 2s / 5s 60ms / 3ms 696.631us …),
|
||||
* **绝不出现科学计数法**。
|
||||
*
|
||||
* ⚠️⚠️ **不要在这里做舍入**(用户 2026-11-03 明确要求):
|
||||
* 旧实现先把值舍入到 3 位**有效数字**再格式化,把真实尾数抹掉了 ——
|
||||
* `0.003696631s` 被显示成 `3ms 700us`(而正确是 `3ms 696.631us`)。
|
||||
* 现在一律用**真实值**(`FormatDurationCompound` 内部把次级单位保留 3 位小数)。
|
||||
*
|
||||
* @param [IN] seconds 时间间隔(秒)。
|
||||
* @return 文本。
|
||||
@@ -1344,7 +1327,7 @@ namespace jdi
|
||||
{
|
||||
return L"—";
|
||||
}
|
||||
return FormatDurationCompound(RoundIntervalForDisplay(seconds));
|
||||
return FormatDurationCompound(seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5458,16 +5458,21 @@ namespace jdi
|
||||
minInterval = resampleItem->minInterval;
|
||||
// 「最大 / 最小数据间隔」= 自适应单位的**小数**文本(绝不用科学计数法),
|
||||
// 末尾追加一个括号内的「对应频率」尾缀(单位在 Hz/kHz/MHz/GHz 之间自适应)。
|
||||
// ⚠️ 频率必须由**同一份舍入后的间隔**换算,否则两列会对不上
|
||||
// (例如显示 `5us` 却给出 `199.99937 kHz`)。
|
||||
//
|
||||
// ⚠️⚠️ 全部使用**真实值**(用户 2026-11-03 明确要求):
|
||||
// * 时间间隔:`FormatDurationCompound` 会把次级单位保留 3 位小数
|
||||
// ⇒ `0.003696631s` 显示为 `3ms 696.631us`(旧实现舍入到 3 位有效数字
|
||||
// 得到 `3ms 700us`,把真实尾数抹掉了);
|
||||
// * 频率:由**未舍入的真实间隔**换算 ⇒ `270.517 Hz`(旧实现用舍入后的
|
||||
// `3.70ms` 换算得到 `270.27 Hz`,与输入框不一致)。
|
||||
// 两条路径都用真实值 ⇒ 统计行与输入框天然一致。
|
||||
const auto intervalWithFrequency = [](double seconds) -> std::wstring
|
||||
{
|
||||
const double shown = RoundIntervalForDisplay(seconds);
|
||||
std::wstring text = FormatDurationCompound(shown);
|
||||
if (std::isfinite(shown) && shown > 0.0)
|
||||
std::wstring text = FormatDurationCompound(seconds);
|
||||
if (std::isfinite(seconds) && seconds > 0.0)
|
||||
{
|
||||
text += L"(";
|
||||
text += FormatFrequencyText(1.0 / shown);
|
||||
text += FormatFrequencyText(1.0 / seconds);
|
||||
text += L")";
|
||||
}
|
||||
return text;
|
||||
@@ -5495,19 +5500,13 @@ namespace jdi
|
||||
{
|
||||
// 非编辑态:自适应单位 + 小数(与「最大/最小数据间隔」同一套单位形式)。
|
||||
// 编辑态:只显示**秒**数值(不带单位),由 `PaintEditField` 绘制。
|
||||
// ⚠️ 间隔文本必须与统计行**同一份舍入值**(`RoundIntervalForDisplay`),
|
||||
// 否则统计行显示 `3ms 700us` 而输入框显示 `3ms 696.631us`(用户 2026-11-03)。
|
||||
paintInputRow(layout.rowIntervalField[rowIndex], kResampleIntervalLabel,
|
||||
FormatIntervalText(interval), editingInterval);
|
||||
}
|
||||
if (rowIndex < layout.rowFrequencyField.size())
|
||||
{
|
||||
// ⚠️ 频率必须由**与间隔输入框同一份显示值**换算(`RoundIntervalForDisplay`),
|
||||
// 否则统计行写 `270.27 Hz`(3.70ms 换算)而这一行写 `270.517 Hz`
|
||||
// (3.696631ms 换算)—— 用户 2026-11-03 报告的"两者不一致"。
|
||||
const double shownInterval =
|
||||
(interval > 0.0) ? RoundIntervalForDisplay(interval) : 0.0;
|
||||
const double hertz = (shownInterval > 0.0) ? (1.0 / shownInterval) : 0.0;
|
||||
// ⚠️ 频率同样用**真实间隔**换算(与时间间隔行同源)⇒ `270.517 Hz`。
|
||||
const double hertz = (interval > 0.0) ? (1.0 / interval) : 0.0;
|
||||
// 非编辑态:频率单位自适应(Hz/kHz/MHz/GHz);编辑态:只显示 Hz 数值。
|
||||
paintInputRow(layout.rowFrequencyField[rowIndex], kResampleFrequencyLabel,
|
||||
(hertz > 0.0) ? FormatFrequencyText(hertz) : L"—",
|
||||
|
||||
Reference in new issue
Block a user