2025-08-20 23:06:28 +08:00
|
|
|
|
#include "Basic.h"
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief map 映射函数,把x的值,映射到out_min到out_max的范围内
|
|
|
|
|
|
* @param x 需要映射的值
|
|
|
|
|
|
* @param in_min x有可能的最小值
|
|
|
|
|
|
* @param in_max x有可能的最大值
|
|
|
|
|
|
* @param out_min 输出的最小值
|
|
|
|
|
|
* @param out_max 输出的最大值
|
|
|
|
|
|
* @return 映射结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
M_d64 map(M_d64 x, M_d64 in_min, M_d64 in_max, M_d64 out_min, M_d64 out_max) {
|
|
|
|
|
|
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
|
|
|
|
|
}
|
2025-10-10 17:44:10 +08:00
|
|
|
|
void Sleep_ms(M_u16 msec){
|
2025-08-20 23:06:28 +08:00
|
|
|
|
QTime _Timer = QTime::currentTime().addMSecs(msec);
|
|
|
|
|
|
while( QTime::currentTime() < _Timer )
|
|
|
|
|
|
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
|
|
|
|
|
}
|
2025-09-15 22:28:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取 32 位数据的第 N 位状态
|
|
|
|
|
|
* @param data 32 位数据源(支持 uint32_t 或 int32_t)
|
|
|
|
|
|
* @param bitIndex 位索引(0 = 最低位/第1位,31 = 最高位/第32位)
|
|
|
|
|
|
* @param defaultValue 索引越界时的默认返回值(默认 false)
|
|
|
|
|
|
* @return bool 位状态:true = 1,false = 0
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool getBitOf32Data(uint32_t data, int bitIndex, bool defaultValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. 边界检查:32位数据的索引范围是 0~31,超出则返回默认值
|
|
|
|
|
|
if (bitIndex < 0 || bitIndex > 31) {
|
|
|
|
|
|
qWarning() << "[getBitOf32Data] 位索引越界!当前索引:" << bitIndex
|
|
|
|
|
|
<< ",允许范围:0~31";
|
|
|
|
|
|
return defaultValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 位运算核心逻辑:
|
|
|
|
|
|
// - (1U << bitIndex):生成“指定位为1,其他位为0”的掩码(1U 确保无符号移位,避免符号位问题)
|
|
|
|
|
|
// - (data & 掩码):按位与操作,若结果非0,说明指定位为1;否则为0
|
|
|
|
|
|
return (static_cast<uint32_t>(data) & (1U << bitIndex)) != 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 将 32 位数据的第 N 位设为 1
|
|
|
|
|
|
* @param data 原始 32 位数据(按引用修改)
|
|
|
|
|
|
* @param bitIndex 位索引(0 = 最低位,31 = 最高位)
|
|
|
|
|
|
* @return bool 成功返回 true;若索引越界返回 false,且不修改 data
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool setBitOf32Data(uint32_t &data, int bitIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (bitIndex < 0 || bitIndex > 31) {
|
|
|
|
|
|
qWarning().noquote() << "[setBitOf32Data] 位索引越界!索引:" << bitIndex;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
data |= (1U << bitIndex); // 置 1
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 将 32 位数据的第 N 位清 0
|
|
|
|
|
|
* @param data 原始 32 位数据(按引用修改)
|
|
|
|
|
|
* @param bitIndex 位索引(0 = 最低位,31 = 最高位)
|
|
|
|
|
|
* @return bool 成功返回 true;若索引越界返回 false,且不修改 data
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool clearBitOf32Data(uint32_t &data, int bitIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (bitIndex < 0 || bitIndex > 31) {
|
|
|
|
|
|
qWarning().noquote() << "[clearBitOf32Data] 位索引越界!索引:" << bitIndex;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
data &= ~(1U << bitIndex); // 清 0
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 将 32 位数据的第 N 位设为指定状态
|
|
|
|
|
|
* @param data 原始 32 位数据(按引用修改)
|
|
|
|
|
|
* @param bitIndex 位索引(0 = 最低位,31 = 最高位)
|
|
|
|
|
|
* @param bitValue 要写入的位值:true = 1,false = 0
|
|
|
|
|
|
* @return bool 成功返回 true;若索引越界返回 false,且不修改 data
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool writeBitOf32Data(uint32_t &data, int bitIndex, bool bitValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
return bitValue ? setBitOf32Data(data, bitIndex)
|
|
|
|
|
|
: clearBitOf32Data(data, bitIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 将 QVariant 按“先转字符串判断小数点”逻辑格式化
|
|
|
|
|
|
* @param variant:待转换的 QVariant 数据
|
|
|
|
|
|
* @param decimalDigits:需要保留的小数位数(默认2位,可自定义)
|
|
|
|
|
|
* @return 格式化后的字符串
|
|
|
|
|
|
*/
|
|
|
|
|
|
QString variantToFormattedString(const QVariant& variant, int decimalDigits) {
|
|
|
|
|
|
// 1. 安全校验:小数位数不能为负数
|
|
|
|
|
|
if (decimalDigits < 0) {
|
|
|
|
|
|
decimalDigits = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 第一步:先将 QVariant 转为原始字符串(不做任何数值格式化)
|
|
|
|
|
|
QString originalStr = variant.toString();
|
|
|
|
|
|
// 处理空字符串情况
|
|
|
|
|
|
if (originalStr.isEmpty()) {
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 第二步:过滤非数字字符串(仅对数字字符串做小数处理)
|
|
|
|
|
|
// 正则匹配:整数(如 "123"、"-456")或浮点数(如 "123.45"、".67"、"89.")
|
|
|
|
|
|
QRegExp numRegExp("^-?\\d+(\\.\\d*)?$");
|
|
|
|
|
|
if (!numRegExp.exactMatch(originalStr)) {
|
|
|
|
|
|
return originalStr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 第三步:判断字符串是否含小数点,按需格式化
|
|
|
|
|
|
if (originalStr.contains('.')) {
|
|
|
|
|
|
// 有小数点:解析为浮点数,保留指定小数位数(四舍五入)
|
|
|
|
|
|
bool ok = false;
|
|
|
|
|
|
double num = originalStr.toDouble(&ok);
|
|
|
|
|
|
if (ok) {
|
|
|
|
|
|
// 用 'f' 格式确保固定小数位数(如 decimalDigits=3 时,123.4→123.400)
|
|
|
|
|
|
return QString::number(num, 'f', decimalDigits);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 极端情况:匹配正则但无法解析(如 ".abc",实际正则已过滤),返回原字符串
|
|
|
|
|
|
return originalStr;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 无小数点:直接返回原始整数字符串(不受小数位数影响)
|
|
|
|
|
|
return originalStr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|