保留三位有效数字和保留小数点后三位数的区别

745 阅读2分钟

区别

1. 保留三位有效数字

有效数字是从第一个非零数字开始计算的位数,包括小数点前后的数字。

特点

  • 关注数字的精确度而非小数位数
  • 会改变数字的表示形式以适应有效位数要求
  • 对很大或很小的数字会自动使用科学计数法

例如 123.456 → 123 (三位有效数字); 0.00123456 → 0.00123 (三位有效数字); 123456 → 1.23×10⁵ (三位有效数字);

2. 保留小数点后三位

这是固定小数位数的表示方法,不考虑有效数字。

特点

  • 固定显示小数点后三位
  • 不会改变数字的量级表示
  • 会进行四舍五入但不会改用科学计数法

例如: 123.456789 → 123.457; 0.00123456 → 0.001; 123456 → 123456.000;

js实现代码和校验代码

1. 保留三位有效数字

/**
 * 格式化数字,保留三位有效数字(效果不是很好,不建议使用该方法)
 * @param num 输入的数字(可以是字符串或数字)
 * @returns 格式化后的三位有效数字字符串
 */
function formatToThreeSignificantDigits(num: number | string): string {
  // 1. 转换为数字并检查有效性
  const parsedNum = Number(num);
  if (isNaN(parsedNum)) return String(num); // 非数字直接返回原值
  if (parsedNum === 0) return "0.00"; // 零值特殊处理

  // 2. 计算有效数字位数
  const numStr = parsedNum.toString();
  let [integerPart, decimalPart = ""] = numStr.split(".");

  // 处理科学计数法(如 1.23e-4)
  if (numStr.includes("e")) {
    return parsedNum.toPrecision(3);
  }

  // 3. 提取有效数字(去掉前导零)
  let significantDigits = integerPart.replace(/^0+/, "") + decimalPart;
  significantDigits = significantDigits.replace(/^0+/, ""); // 再次处理 0.xxx 情况

  // 4. 如果有效数字不足 3 位,补零(如 0.001 → 0.00100)
  if (significantDigits.length < 3) {
    const zerosToAdd = 3 - significantDigits.length;
    decimalPart += "0".repeat(zerosToAdd);
    return `${integerPart}.${decimalPart}`;
  }

  // 5. 如果有效数字超过 3 位,四舍五入
  if (significantDigits.length > 3) {
    const rounded = parseFloat(numStr).toPrecision(3);
    return rounded.includes(".") ? rounded : `${rounded}.00`; // 确保小数点后两位
  }

  // 6. 刚好 3 位有效数字,直接返回(保留末尾零)
  return numStr;
}

// 校验方法(可用√)
export const ruleByPositiveSignificant3 = reactive({
  message: '请输入保留三位有效数字的非零正数',
  trigger: 'change',
  validator: positiveSignificant3,
});
function positiveSignificant3(rule: RuleObject, value: any, callback: (error?: string) => void) {
  if (!value) return Promise.reject();

  // 移除所有非数字字符(除了小数点),并检查格式
  const numStr = String(value).replace(/[^0-9.]/g, '');
  if (!/^(?!0+$)(\d+\.?\d*|\.\d+)$/.test(numStr)) {
    return Promise.reject();
  }

  // 提取有效数字(去掉前导零和小数点)
  const significantDigits = numStr
    .replace(/^0+/, '') // 去掉前导零
    .replace(/\./, '') // 去掉小数点
    .replace(/^0+/, ''); // 再次去掉前导零(如 0.025 → 025 → 25)

  // 检查有效数字位数
  if (significantDigits.length !== 3) {
    return Promise.reject();
  }

  return Promise.resolve();
}

2. 保留小数点后三位

const fixedDecimals = (num) => {
  return parseFloat(num.toFixed(3));
}