Javascript提高:小数精度和随机数-由Deepseek产生

在 JavaScript 中,处理小数精度和生成随机数是开发中非常常见的需求。下面分别对保留小数随机函数进行详解,包括核心方法、使用示例、常见陷阱和最佳实践。


一、保留小数(数值格式化)

1. Number.prototype.toFixed(digits)

  • 功能 :将数字转换为字符串,并保留指定的小数位数(四舍五入)。
  • 参数digits -- 0~100 之间的整数,表示小数位数。
  • 返回值字符串(注意不是数字)。
  • 特点:自动补零或舍入,但存在浮点数精度导致的"非标准舍入"问题。
javascript 复制代码
const num = 3.14159;
console.log(num.toFixed(2)); // "3.14"  四舍五入
console.log(num.toFixed(4)); // "3.1416"

// 补零示例
const num2 = 5;
console.log(num2.toFixed(2)); // "5.00"

// ⚠️ 浮点数精度问题
console.log((1.005).toFixed(2)); // 期望 "1.01",实际 "1.00" (因为 1.005 在计算机中实际存储为 1.004999...)

解决方案 :对于精确的货币计算,推荐先乘以 10 的幂次转为整数运算,或使用 Math.round 封装。

javascript 复制代码
function preciseToFixed(num, digits) {
    const factor = Math.pow(10, digits);
    return (Math.round(num * factor) / factor).toFixed(digits);
}
console.log(preciseToFixed(1.005, 2)); // "1.01"

2. Number.prototype.toPrecision(precision)

  • 功能 :返回数字的有效数字 位数(四舍五入),若整数部分位数超过 precision,则返回科学计数法。
  • 参数precision -- 1~100 之间的整数。
  • 返回值:字符串。
javascript 复制代码
const num = 123.456;
console.log(num.toPrecision(4)); // "123.5"
console.log(num.toPrecision(2)); // "1.2e+2"  科学计数法
console.log((0.00123).toPrecision(2)); // "0.0012"

3. Math.round() + 乘除法(保留小数并返回数字)

  • 如果需要保留小数位数但保持数字类型(而非字符串),常用此方法。
  • 原理:乘以 10^n 取整,再除以 10^n
javascript 复制代码
function roundTo(num, digits) {
    const factor = Math.pow(10, digits);
    return Math.round(num * factor) / factor;
}

console.log(roundTo(3.14159, 2)); // 3.14
console.log(roundTo(1.005, 2));   // 1.01  (比 toFixed 更精确)
console.log(typeof roundTo(3.14, 1)); // "number"

⚠️ 注意 Math.round 采用"四舍五入",对于 -1.005 等负数同样适用。

4. Intl.NumberFormat(国际化格式化)

  • 适合需要格式化显示(如千位分隔符、货币符号、特定区域的小数点风格)。
  • 返回字符串,但支持更丰富的本地化配置。
javascript 复制代码
const formatter = new Intl.NumberFormat('en-US', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
});
console.log(formatter.format(1234.567)); // "1,234.57"

// 中文环境
const cnFormatter = new Intl.NumberFormat('zh-CN', {
    minimumFractionDigits: 2,
});
console.log(cnFormatter.format(1234.5)); // "1,234.50"

5. 避免浮点数陷阱的通用原则

  • 对于财务、支付等要求精确小数的场景,推荐使用整数(分、厘)存储和运算,仅在展示时转为带小数的字符串。
  • 或使用第三方库:decimal.jsbig.jsbignumber.js

二、随机函数

JavaScript 中最常用的随机函数是 Math.random(),它返回一个 伪随机 浮点数,范围 [0, 1)(包含 0,不包含 1)。

1. 基础用法:Math.random()

javascript 复制代码
console.log(Math.random()); // 例如 0.23145678912345678

2. 生成指定范围的随机数

2.1 生成 [0, max) 的浮点数
javascript 复制代码
function randomFloat(max) {
    return Math.random() * max;
}
console.log(randomFloat(10)); // 例如 3.789
2.2 生成 [min, max) 的浮点数
javascript 复制代码
function randomRange(min, max) {
    return min + Math.random() * (max - min);
}
console.log(randomRange(5, 10)); // 例如 7.234
2.3 生成 [min, max] 的整数(包含两端)
  • 使用 Math.floor():注意边界处理,公式为 Math.floor(Math.random() * (max - min + 1)) + min
javascript 复制代码
function randomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomInt(1, 6)); // 模拟骰子:1~6 等概率
  • 使用 Math.round() 会导致端点概率不均等(两端概率减半),不推荐
2.4 生成 [min, max) 的整数(包含 min,不包含 max)
javascript 复制代码
function randomIntExclusiveMax(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
}
console.log(randomIntExclusiveMax(1, 10)); // 1~9

3. 其他常见随机应用

3.1 随机布尔值
javascript 复制代码
const randomBool = Math.random() < 0.5; // true/false 概率各半
3.2 从数组中随机取一项
javascript 复制代码
const arr = ['apple', 'banana', 'cherry'];
const randomItem = arr[Math.floor(Math.random() * arr.length)];
3.3 随机颜色(十六进制)
javascript 复制代码
function randomHexColor() {
    return '#' + Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, '0');
}
console.log(randomHexColor()); // 例如 "#a3f2c1"
3.4 随机字符串(指定长度)
javascript 复制代码
function randomString(length) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
        result += chars[Math.floor(Math.random() * chars.length)];
    }
    return result;
}
console.log(randomString(8)); // 例如 "Kj3nP9xQ"

4. 安全性:密码学安全随机数

Math.random() 不适合用于安全敏感场景(如生成令牌、验证码、密钥),因为它是伪随机的且种子可预测。

应使用 Web Crypto API 的 crypto.getRandomValues()(浏览器)或 crypto.randomBytes()(Node.js)。

浏览器端示例(生成 0~255 的随机整数数组)
javascript 复制代码
const array = new Uint32Array(1);
crypto.getRandomValues(array);
const secureRandom = array[0] / (0xffffffff + 1); // 得到 [0,1) 的高质量随机数
console.log(secureRandom);

生成随机整数(例如 1~100):

javascript 复制代码
function secureRandomInt(min, max) {
    const range = max - min + 1;
    const maxValid = Math.floor(0xffffffff / range) * range;
    let randomValue;
    do {
        randomValue = crypto.getRandomValues(new Uint32Array(1))[0];
    } while (randomValue >= maxValid);
    return min + (randomValue % range);
}
console.log(secureRandomInt(1, 100));

5. 伪随机种子(进阶)

Math.random() 无法手动设置种子,但若需要可复现的随机序列(例如游戏地图生成),可以实现一个简单的线性同余生成器(LCG)或使用 seedrandom 库。

javascript 复制代码
// 简易 LCG(不用于密码学)
function createSeededRandom(seed) {
    let state = seed;
    return function() {
        state = (state * 1103515245 + 12345) & 0x7fffffff;
        return state / 0x7fffffff;
    };
}
const rng = createSeededRandom(42);
console.log(rng()); // 固定序列的第一个随机数
console.log(rng());

总结对比表

需求 推荐方法 返回类型 注意事项
保留 n 位小数并显示(四舍五入) num.toFixed(n) 字符串 存在浮点数精度问题
保留 n 位小数并继续计算 Math.round(num * 10^n) / 10^n 数字 比 toFixed 更精确,但仍受浮点限制
本地化格式化(千位分隔等) Intl.NumberFormat 字符串 支持区域敏感
生成 [0,1) 随机浮点数 Math.random() 数字 伪随机,不安全
生成 [min,max] 随机整数 Math.floor(Math.random()*(max-min+1))+min 数字 等概率,常用
生成 [min,max) 随机浮点数 min + Math.random() * (max - min) 数字
安全随机(密码学) crypto.getRandomValues() 多种类型 用于令牌、验证码等

掌握以上方法,可以轻松处理 JavaScript 中绝大部分小数格式化和随机数生成的需求。

相关推荐
椰猫子2 小时前
Javaweb(Filter、Listener、AJAX、JSON)
java·开发语言
盛世宏博北京2 小时前
以太网温湿度传感器运维技巧,提升设备稳定性与使用寿命
开发语言·php·以太网温湿度传感器
代码改善世界3 小时前
【MATLAB初阶】矩阵操作(一)
开发语言·matlab·矩阵
覆东流3 小时前
第1天:Python环境搭建 & 第一个程序
开发语言·后端·python
朝阳5813 小时前
rust 交叉编译指南
开发语言·后端·rust
冴羽4 小时前
请愿书:Node.js 核心代码不应该包含 AI 代码!
前端·javascript·node.js
mmmmm123424 小时前
深入 DOM 查询底层:HTMLCollection 动态原理与 querySelectorAll 静态快照解析
前端·javascript
淸湫4 小时前
前端JavaScript:数据类型、实例对象 、内置对象、构造函数之间的关系
javascript
量子炒饭大师4 小时前
【C++ 进阶】Cyber霓虹掩体下的代码拟态——【面向对象编程 之 多态】一文带你搞懂C++面向对象编程中的三要素之一————多态!
开发语言·c++·多态