简体中文 繁體中文 English Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français Japanese

站内搜索

搜索
AI 风月

活动公告

03-01 22:34
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

JavaScript数字处理完全指南从基础运算到高级应用助你轻松掌握编程中的数字技巧提升开发效率解决实际问题

3万

主题

602

科技点

3万

积分

白金月票

碾压王

积分
32704

立华奏

发表于 2025-9-3 09:50:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

JavaScript作为一门动态类型语言,数字处理是日常开发中最常见的任务之一。无论是简单的算术运算、复杂的数学计算,还是数据格式化和精度控制,JavaScript都提供了丰富的API和方法。然而,由于JavaScript采用IEEE 754标准的双精度浮点数表示数字,开发者在处理数字时常常会遇到精度问题、范围限制和各种特殊情况的挑战。本指南将全面介绍JavaScript中的数字处理技术,从基础的数学运算到高级应用技巧,帮助你轻松掌握编程中的数字处理方法,提升开发效率,并解决实际项目中遇到的各种数字相关问题。

JavaScript中的数字基础

数字类型

在JavaScript中,所有数字都以64位双精度浮点数(double-precision floating-point format)表示,这是根据IEEE 754标准定义的。这意味着JavaScript没有像其他语言那样的整数类型,所有数字(无论整数还是小数)都属于number类型。
  1. let integer = 42;      // 整数
  2. let float = 42.0;     // 浮点数,但在JavaScript中与整数表示相同
  3. let negative = -42;   // 负数
  4. let octal = 0o52;     // 八进制表示法 (ES6)
  5. let hex = 0x2A;       // 十六进制表示法
  6. let binary = 0b101010; // 二进制表示法 (ES6)
  7. console.log(typeof integer);  // "number"
  8. console.log(typeof float);    // "number"
  9. console.log(typeof negative); // "number"
复制代码

数字表示方法

JavaScript提供了多种表示数字的方法,包括十进制、二进制、八进制和十六进制:
  1. // 十进制(常规表示)
  2. let decimal = 255;
  3. // 二进制(以0b或0B开头)
  4. let binary = 0b11111111;  // 等于十进制的255
  5. // 八进制(以0o或0O开头,ES6标准)
  6. let octal = 0o377;       // 等于十进制的255
  7. // 十六进制(以0x或0X开头)
  8. let hex = 0xFF;          // 等于十进制的255
  9. console.log(decimal === binary);  // true
  10. console.log(decimal === octal);   // true
  11. console.log(decimal === hex);     // true
复制代码

特殊数字值

JavaScript中有几个特殊的数字值,了解它们对于正确处理数字运算非常重要:
  1. // Infinity - 表示正无穷大
  2. console.log(1 / 0);        // Infinity
  3. console.log(Number.MAX_VALUE * 2); // Infinity
  4. // -Infinity - 表示负无穷大
  5. console.log(-1 / 0);       // -Infinity
  6. console.log(-Number.MAX_VALUE * 2); // -Infinity
  7. // NaN - Not a Number,表示不是一个数字
  8. console.log(0 / 0);        // NaN
  9. console.log(parseInt('abc')); // NaN
  10. // 检查NaN
  11. console.log(NaN === NaN);  // false,NaN是唯一不等于自身的值
  12. console.log(isNaN(NaN));   // true,使用isNaN函数检查
  13. console.log(Number.isNaN(NaN)); // true,更严格的检查方式
  14. // 检查有限数字
  15. console.log(isFinite(100));         // true
  16. console.log(isFinite(Infinity));     // false
  17. console.log(isFinite(NaN));          // false
  18. // 最大和最小安全整数
  19. console.log(Number.MAX_SAFE_INTEGER);  // 9007199254740991
  20. console.log(Number.MIN_SAFE_INTEGER);  // -9007199254740991
  21. // 检查是否为安全整数
  22. console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true
  23. console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
复制代码

基础数学运算

基本算术运算

JavaScript提供了基本的算术运算符,包括加(+)、减(-)、乘(*)、除(/)和取模(%):
  1. // 基本算术运算
  2. let a = 10;
  3. let b = 3;
  4. console.log(a + b);  // 13 - 加法
  5. console.log(a - b);  // 7  - 减法
  6. console.log(a * b);  // 30 - 乘法
  7. console.log(a / b);  // 3.3333333333333335 - 除法
  8. console.log(a % b);  // 1  - 取模(余数)
  9. // 增量和减量
  10. let x = 5;
  11. x++;          // 后增量,x变为6
  12. console.log(x); // 6
  13. ++x;          // 前增量,x变为7
  14. console.log(x); // 7
  15. x--;          // 后减量,x变为6
  16. console.log(x); // 6
  17. --x;          // 前减量,x变为5
  18. console.log(x); // 5
  19. // 复合赋值运算符
  20. let y = 10;
  21. y += 5;  // 等同于 y = y + 5,y变为15
  22. y -= 3;  // 等同于 y = y - 3,y变为12
  23. y *= 2;  // 等同于 y = y * 2,y变为24
  24. y /= 4;  // 等同于 y = y / 4,y变为6
  25. y %= 4;  // 等同于 y = y % 4,y变为2
复制代码

取整运算

在JavaScript中,有几种方法可以对数字进行取整:
  1. let num = 3.7;
  2. // Math.round() - 四舍五入
  3. console.log(Math.round(num));  // 4
  4. // Math.floor() - 向下取整
  5. console.log(Math.floor(num));  // 3
  6. // Math.ceil() - 向上取整
  7. console.log(Math.ceil(num));   // 4
  8. // Math.trunc() - 去除小数部分(ES6)
  9. console.log(Math.trunc(num));  // 3
  10. // 位运算取整(适用于32位整数)
  11. console.log(3.7 | 0);     // 3
  12. console.log(~~3.7);       // 3
  13. console.log(3.7 >> 0);    // 3
  14. // 注意:负数时的区别
  15. let negativeNum = -3.7;
  16. console.log(Math.round(negativeNum));  // -4
  17. console.log(Math.floor(negativeNum));  // -4
  18. console.log(Math.ceil(negativeNum));   // -3
  19. console.log(Math.trunc(negativeNum));  // -3
复制代码

随机数生成

JavaScript的Math.random()函数可以生成0到1之间的随机数(不包括1),我们可以利用它来生成各种范围的随机数:
  1. // 生成0到1之间的随机数
  2. console.log(Math.random());  // 例如:0.123456789
  3. // 生成0到10之间的随机整数
  4. function getRandomInt(max) {
  5.   return Math.floor(Math.random() * max);
  6. }
  7. console.log(getRandomInt(10));  // 0到9之间的整数
  8. // 生成指定范围内的随机整数
  9. function getRandomRange(min, max) {
  10.   min = Math.ceil(min);
  11.   max = Math.floor(max);
  12.   return Math.floor(Math.random() * (max - min + 1)) + min;
  13. }
  14. console.log(getRandomRange(1, 10));  // 1到10之间的整数
  15. // 生成指定范围内的随机小数
  16. function getRandomFloat(min, max) {
  17.   return Math.random() * (max - min) + min;
  18. }
  19. console.log(getRandomFloat(1.5, 3.5));  // 1.5到3.5之间的小数
  20. // 生成随机布尔值
  21. function getRandomBoolean() {
  22.   return Math.random() < 0.5;
  23. }
  24. console.log(getRandomBoolean());  // true或false
  25. // 从数组中随机选择一个元素
  26. function getRandomItem(array) {
  27.   return array[Math.floor(Math.random() * array.length)];
  28. }
  29. const colors = ['red', 'green', 'blue'];
  30. console.log(getRandomItem(colors));  // 随机返回一个颜色
复制代码

数字格式化

固定小数位数

在显示数字时,我们经常需要控制小数位数,可以使用toFixed()方法:
  1. let num = 3.14159265359;
  2. // 保留2位小数
  3. console.log(num.toFixed(2));  // "3.14"
  4. // 保留0位小数(四舍五入为整数)
  5. console.log(num.toFixed(0));  // "3"
  6. // 注意:toFixed返回的是字符串,不是数字
  7. console.log(typeof num.toFixed(2));  // "string"
  8. // 如果需要数字类型,需要转换
  9. let formattedNum = parseFloat(num.toFixed(2));
  10. console.log(typeof formattedNum);  // "number"
  11. // 处理不足小数位数的情况
  12. let shortNum = 5;
  13. console.log(shortNum.toFixed(3));  // "5.000" - 自动补零
复制代码

科学计数法

对于非常大或非常小的数字,可以使用toExponential()方法将其转换为科学计数法表示:
  1. let bigNum = 123456789;
  2. let smallNum = 0.000012345;
  3. // 转换为科学计数法
  4. console.log(bigNum.toExponential());  // "1.23456789e+8"
  5. console.log(smallNum.toExponential());  // "1.2345e-5"
  6. // 指定小数位数
  7. console.log(bigNum.toExponential(2));  // "1.23e+8"
  8. console.log(smallNum.toExponential(3));  // "1.235e-5"
  9. // toExponential也返回字符串
  10. console.log(typeof bigNum.toExponential());  // "string"
复制代码

数字分隔符

为了提高大数字的可读性,ES2021引入了数字分隔符(_):
  1. // 使用数字分隔符提高可读性
  2. let billion = 1_000_000_000;
  3. let bytes = 0b1111_1111_1111_1111;
  4. let hex = 0xFF_FF_FF_FF;
  5. console.log(billion);  // 1000000000
  6. console.log(bytes);    // 65535
  7. console.log(hex);      // 4294967295
  8. // 分隔符可以放在数字之间的任何位置,但不能放在开头、结尾或小数点旁边
  9. let valid = 1_2_3.4_5;      // 有效
  10. let invalid = _123;         // 无效
  11. let alsoInvalid = 123_;     // 无效
  12. let alsoAlsoInvalid = 123._45; // 无效
复制代码

货币格式化

在处理货币时,我们需要精确的格式化,可以使用Intl.NumberFormat对象:
  1. // 基本货币格式化
  2. let amount = 123456.789;
  3. // 美元格式
  4. let usdFormatter = new Intl.NumberFormat('en-US', {
  5.   style: 'currency',
  6.   currency: 'USD'
  7. });
  8. console.log(usdFormatter.format(amount));  // "$123,456.79"
  9. // 欧元格式
  10. let eurFormatter = new Intl.NumberFormat('de-DE', {
  11.   style: 'currency',
  12.   currency: 'EUR'
  13. });
  14. console.log(eurFormatter.format(amount));  // "123.456,79 €"
  15. // 人民币格式
  16. let cnyFormatter = new Intl.NumberFormat('zh-CN', {
  17.   style: 'currency',
  18.   currency: 'CNY'
  19. });
  20. console.log(cnyFormatter.format(amount));  // "¥123,456.79"
  21. // 不使用货币符号,只格式化数字
  22. let numberFormatter = new Intl.NumberFormat('en-US');
  23. console.log(numberFormatter.format(amount));  // "123,456.789"
  24. // 指定最小和最大小数位数
  25. let preciseFormatter = new Intl.NumberFormat('en-US', {
  26.   minimumFractionDigits: 2,
  27.   maximumFractionDigits: 2
  28. });
  29. console.log(preciseFormatter.format(amount));  // "123,456.79"
复制代码

高级数字处理

大整数(BigInt)处理

JavaScript的number类型只能安全表示-2^53到2^53之间的整数(即-9007199254740992到9007199254740992)。对于超出这个范围的整数,ES2020引入了BigInt类型:
  1. // 创建BigInt - 在数字后加n或使用BigInt()构造函数
  2. let bigInt1 = 9007199254740993n;  // 超出安全整数范围
  3. let bigInt2 = BigInt(9007199254740993);
  4. console.log(typeof bigInt1);  // "bigint"
  5. console.log(bigInt1 === bigInt2);  // true
  6. // BigInt运算
  7. console.log(100n + 50n);     // 150n
  8. console.log(100n - 50n);     // 50n
  9. console.log(100n * 50n);     // 5000n
  10. console.log(100n / 50n);     // 2n (注意:BigInt除法会向下取整)
  11. console.log(100n % 50n);     // 0n
  12. // 比较运算
  13. console.log(10n > 5n);       // true
  14. console.log(10n < 5n);       // false
  15. console.log(10n === 10);     // false (BigInt和number类型不同)
  16. console.log(10n == 10);      // true (宽松相等)
  17. // 位运算
  18. console.log(5n | 3n);        // 7n
  19. console.log(5n & 3n);        // 1n
  20. console.log(5n ^ 3n);        // 6n
  21. console.log(~5n);            // -6n
  22. // BigInt与普通数字的混合运算会抛出错误
  23. try {
  24.   console.log(10n + 5);  // TypeError: Cannot mix BigInt and other types
  25. } catch (e) {
  26.   console.error(e.message);
  27. }
  28. // 需要显式转换
  29. console.log(10n + BigInt(5));  // 15n
  30. console.log(Number(10n) + 5);  // 15
  31. // 实际应用:计算大数阶乘
  32. function factorial(n) {
  33.   if (n === 0n) return 1n;
  34.   return n * factorial(n - 1n);
  35. }
  36. console.log(factorial(20n));  // 2432902008176640000n
  37. // 使用普通number计算20的阶乘会得到不准确的结果
  38. console.log(factorial(20));   // 2432902008176640000 (但超过20会不准确)
复制代码

精确计算(避免浮点数精度问题)

JavaScript使用二进制浮点数表示十进制数字,这会导致一些精度问题,例如:
  1. // 浮点数精度问题示例
  2. console.log(0.1 + 0.2);  // 0.30000000000000004
  3. console.log(0.3 - 0.1);  // 0.19999999999999998
  4. console.log(0.1 * 0.2);  // 0.020000000000000004
  5. console.log(0.3 / 0.1);  // 2.9999999999999996
复制代码

解决这些精度问题的方法有多种:
  1. function add(a, b) {
  2.   return parseFloat((a + b).toFixed(10));
  3. }
  4. console.log(add(0.1, 0.2));  // 0.3
复制代码
  1. function preciseAdd(a, b, precision = 10) {
  2.   const factor = Math.pow(10, precision);
  3.   return (Math.round(a * factor) + Math.round(b * factor)) / factor;
  4. }
  5. console.log(preciseAdd(0.1, 0.2));  // 0.3
  6. console.log(preciseAdd(0.15, 0.25));  // 0.4
复制代码
  1. // 假设已经引入了decimal.js库
  2. // <script src="https://cdn.jsdelivr.net/npm/decimal.js@10.4.3/decimal.min.js"></script>
  3. // 使用decimal.js进行精确计算
  4. const Decimal = Decimal; // 在实际环境中,这应该是全局可用的
  5. let a = new Decimal(0.1);
  6. let b = new Decimal(0.2);
  7. console.log(a.plus(b).toString());  // "0.3"
  8. let c = new Decimal(0.15);
  9. let d = new Decimal(0.25);
  10. console.log(c.plus(d).toString());  // "0.4"
复制代码
  1. // 使用BigInt进行精确的小数计算
  2. function preciseDecimalAdd(a, b, precision = 10) {
  3.   const factor = BigInt(Math.pow(10, precision));
  4.   const aInt = BigInt(Math.round(a * Math.pow(10, precision)));
  5.   const bInt = BigInt(Math.round(b * Math.pow(10, precision)));
  6.   const result = aInt + bInt;
  7.   return Number(result) / Number(factor);
  8. }
  9. console.log(preciseDecimalAdd(0.1, 0.2));  // 0.3
  10. console.log(preciseDecimalAdd(0.15, 0.25));  // 0.4
复制代码

数字转换和解析

在JavaScript中,有几种方法可以将字符串转换为数字,或者将数字转换为字符串:
  1. // 字符串转数字
  2. let strNum1 = "123";
  3. let strNum2 = "123.45";
  4. let strNum3 = "123abc";
  5. let strNum4 = "abc123";
  6. // 使用Number()构造函数
  7. console.log(Number(strNum1));  // 123
  8. console.log(Number(strNum2));  // 123.45
  9. console.log(Number(strNum3));  // NaN
  10. console.log(Number(strNum4));  // NaN
  11. // 使用parseInt() - 解析整数
  12. console.log(parseInt(strNum1));  // 123
  13. console.log(parseInt(strNum2));  // 123
  14. console.log(parseInt(strNum3));  // 123
  15. console.log(parseInt(strNum4));  // NaN
  16. // 使用parseFloat() - 解析浮点数
  17. console.log(parseFloat(strNum1));  // 123
  18. console.log(parseFloat(strNum2));  // 123.45
  19. console.log(parseFloat(strNum3));  // 123
  20. console.log(parseFloat(strNum4));  // NaN
  21. // 使用一元加号运算符
  22. console.log(+strNum1);  // 123
  23. console.log(+strNum2);  // 123.45
  24. console.log(+strNum3);  // NaN
  25. console.log(+strNum4);  // NaN
  26. // 数字转字符串
  27. let num1 = 123;
  28. let num2 = 123.45;
  29. // 使用String()函数
  30. console.log(String(num1));  // "123"
  31. console.log(String(num2));  // "123.45"
  32. // 使用toString()方法
  33. console.log(num1.toString());  // "123"
  34. console.log(num2.toString());  // "123.45"
  35. // 使用模板字符串
  36. console.log(`${num1}`);  // "123"
  37. console.log(`${num2}`);  // "123.45"
  38. // 使用空字符串连接
  39. console.log(num1 + "");  // "123"
  40. console.log(num2 + "");  // "123.45"
  41. // 指定进制转换
  42. let hexNum = 255;
  43. console.log(hexNum.toString(16));  // "ff"
  44. console.log(hexNum.toString(8));   // "377"
  45. console.log(hexNum.toString(2));   // "11111111"
  46. // 从不同进制解析
  47. console.log(parseInt("ff", 16));  // 255
  48. console.log(parseInt("377", 8));  // 255
  49. console.log(parseInt("11111111", 2));  // 255
复制代码

实用数字技巧

数字范围限制

在实际开发中,我们经常需要将数字限制在特定范围内:
  1. // 使用Math.min()和Math.max()限制范围
  2. function clamp(value, min, max) {
  3.   return Math.min(Math.max(value, min), max);
  4. }
  5. console.log(clamp(10, 0, 100));   // 10
  6. console.log(clamp(-10, 0, 100));  // 0
  7. console.log(clamp(110, 0, 100));  // 100
  8. // 循环范围(超出范围后从另一端继续)
  9. function wrap(value, min, max) {
  10.   const range = max - min;
  11.   return ((value - min) % range + range) % range + min;
  12. }
  13. console.log(wrap(5, 0, 10));    // 5
  14. console.log(wrap(15, 0, 10));   // 5
  15. console.log(wrap(-5, 0, 10));   // 5
  16. // 将数字映射到不同范围
  17. function map(value, fromMin, fromMax, toMin, toMax) {
  18.   return (value - fromMin) * (toMax - toMin) / (fromMax - fromMin) + toMin;
  19. }
  20. console.log(map(5, 0, 10, 0, 100));  // 50
  21. console.log(map(2, 0, 10, 0, 100));  // 20
  22. console.log(map(8, 0, 10, 0, 100));  // 80
  23. // 线性插值
  24. function lerp(start, end, t) {
  25.   return start * (1 - t) + end * t;
  26. }
  27. console.log(lerp(0, 100, 0.5));  // 50
  28. console.log(lerp(0, 100, 0.25)); // 25
  29. console.log(lerp(0, 100, 0.75)); // 75
复制代码

数字验证

验证用户输入或处理数据时,我们需要确保数字的有效性:
  1. // 检查是否为有效数字
  2. function isValidNumber(value) {
  3.   return typeof value === 'number' && !isNaN(value) && isFinite(value);
  4. }
  5. console.log(isValidNumber(123));      // true
  6. console.log(isValidNumber(123.45));   // true
  7. console.log(isValidNumber(NaN));      // false
  8. console.log(isValidNumber(Infinity)); // false
  9. console.log(isValidNumber("123"));    // false
  10. console.log(isValidNumber(null));     // false
  11. // 检查是否为整数
  12. function isInteger(value) {
  13.   return typeof value === 'number' && !isNaN(value) && isFinite(value) && value % 1 === 0;
  14. }
  15. console.log(isInteger(123));      // true
  16. console.log(isInteger(123.0));    // true
  17. console.log(isInteger(123.45));   // false
  18. console.log(isInteger("123"));    // false
  19. // 检查是否为安全整数
  20. function isSafeInteger(value) {
  21.   return typeof value === 'number' && !isNaN(value) && isFinite(value) &&
  22.          value % 1 === 0 && value >= Number.MIN_SAFE_INTEGER &&
  23.          value <= Number.MAX_SAFE_INTEGER;
  24. }
  25. console.log(isSafeInteger(123));                           // true
  26. console.log(isSafeInteger(Number.MAX_SAFE_INTEGER));       // true
  27. console.log(isSafeInteger(Number.MAX_SAFE_INTEGER + 1));   // false
  28. console.log(isSafeInteger(9007199254740993));              // false
  29. // 检查是否为数字字符串
  30. function isNumericString(value) {
  31.   return typeof value === 'string' && !isNaN(value) && value.trim() !== '';
  32. }
  33. console.log(isNumericString("123"));      // true
  34. console.log(isNumericString("123.45"));   // true
  35. console.log(isNumericString("123abc"));   // false
  36. console.log(isNumericString("abc123"));   // false
  37. console.log(isNumericString(""));         // false
  38. console.log(isNumericString("   "));      // false
  39. // 检查数字是否在指定范围内
  40. function isInRange(value, min, max) {
  41.   return isValidNumber(value) && value >= min && value <= max;
  42. }
  43. console.log(isInRange(50, 0, 100));   // true
  44. console.log(isInRange(-10, 0, 100));  // false
  45. console.log(isInRange(110, 0, 100));  // false
  46. console.log(isInRange("50", 0, 100)); // false
复制代码

数字性能优化

在处理大量数字计算时,性能优化变得尤为重要:
  1. // 使用位运算代替算术运算(适用于整数)
  2. // 乘以2的幂次方
  3. function multiplyByPowerOfTwo(value, power) {
  4.   return value << power;  // 相当于 value * Math.pow(2, power)
  5. }
  6. console.log(multiplyByPowerOfTwo(5, 3));  // 40 (5 * 8)
  7. // 除以2的幂次方
  8. function divideByPowerOfTwo(value, power) {
  9.   return value >> power;  // 相当于 Math.floor(value / Math.pow(2, power))
  10. }
  11. console.log(divideByPowerOfTwo(40, 3));  // 5 (Math.floor(40 / 8))
  12. // 快速取整(使用位运算)
  13. function fastFloor(value) {
  14.   return value | 0;
  15. }
  16. console.log(fastFloor(3.7));   // 3
  17. console.log(fastFloor(-3.7));  // -3
  18. // 使用查表法代替复杂计算
  19. // 例如:计算正弦值(精度要求不高时)
  20. const sinTable = [];
  21. for (let i = 0; i < 360; i++) {
  22.   sinTable[i] = Math.sin(i * Math.PI / 180);
  23. }
  24. function fastSin(degrees) {
  25.   // 标准化角度到0-359范围
  26.   degrees = degrees % 360;
  27.   if (degrees < 0) degrees += 360;
  28.   return sinTable[Math.round(degrees)];
  29. }
  30. console.log(fastSin(30));    // 约0.5
  31. console.log(fastSin(90));    // 约1
  32. // 使用TypedArray处理大量数字数据
  33. // 创建一个包含100万个随机数的数组
  34. const regularArray = new Array(1000000);
  35. for (let i = 0; i < regularArray.length; i++) {
  36.   regularArray[i] = Math.random();
  37. }
  38. // 使用Float64Array(更高效的内存使用和处理速度)
  39. const typedArray = new Float64Array(1000000);
  40. for (let i = 0; i < typedArray.length; i++) {
  41.   typedArray[i] = Math.random();
  42. }
  43. // 对数组进行操作(例如:计算平均值)
  44. function calculateAverage(array) {
  45.   let sum = 0;
  46.   for (let i = 0; i < array.length; i++) {
  47.     sum += array[i];
  48.   }
  49.   return sum / array.length;
  50. }
  51. // 测试性能
  52. console.time('Regular Array');
  53. const avg1 = calculateAverage(regularArray);
  54. console.timeEnd('Regular Array');
  55. console.time('Typed Array');
  56. const avg2 = calculateAverage(typedArray);
  57. console.timeEnd('Typed Array');
  58. console.log(avg1, avg2);  // 两个平均值应该相近
  59. // 使用Web Workers进行并行计算(主线程代码)
  60. if (typeof Worker !== 'undefined') {
  61.   // 创建Worker代码
  62.   const workerCode = `
  63.     self.onmessage = function(e) {
  64.       const data = e.data;
  65.       let sum = 0;
  66.       for (let i = 0; i < data.length; i++) {
  67.         sum += data[i];
  68.       }
  69.       self.postMessage(sum / data.length);
  70.     };
  71.   `;
  72.   
  73.   // 创建Blob URL
  74.   const blob = new Blob([workerCode], { type: 'application/javascript' });
  75.   const workerUrl = URL.createObjectURL(blob);
  76.   
  77.   // 创建Worker
  78.   const worker = new Worker(workerUrl);
  79.   
  80.   // 发送数据到Worker
  81.   worker.postMessage(typedArray);
  82.   
  83.   // 接收Worker计算结果
  84.   worker.onmessage = function(e) {
  85.     console.log('Worker calculated average:', e.data);
  86.     worker.terminate();
  87.     URL.revokeObjectURL(workerUrl);
  88.   };
  89. }
复制代码

实际应用场景

数据可视化中的数字处理

在数据可视化中,数字处理是必不可少的,例如缩放、格式化和转换:
  1. // 数据缩放 - 将数据映射到可视化区域
  2. class DataScaler {
  3.   constructor(dataMin, dataMax, viewMin, viewMax) {
  4.     this.dataMin = dataMin;
  5.     this.dataMax = dataMax;
  6.     this.viewMin = viewMin;
  7.     this.viewMax = viewMax;
  8.   }
  9.   
  10.   // 数据值转换为视图坐标
  11.   dataToView(dataValue) {
  12.     const dataRange = this.dataMax - this.dataMin;
  13.     const viewRange = this.viewMax - this.viewMin;
  14.     return ((dataValue - this.dataMin) / dataRange) * viewRange + this.viewMin;
  15.   }
  16.   
  17.   // 视图坐标转换为数据值
  18.   viewToData(viewValue) {
  19.     const dataRange = this.dataMax - this.dataMin;
  20.     const viewRange = this.viewMax - this.viewMin;
  21.     return ((viewValue - this.viewMin) / viewRange) * dataRange + this.dataMin;
  22.   }
  23. }
  24. // 使用示例:将温度数据(0-40°C)映射到图表高度(0-500px)
  25. const tempScaler = new DataScaler(0, 40, 500, 0);  // 注意:Y轴通常是从上到下增长的
  26. console.log(tempScaler.dataToView(20));  // 250 (中间位置)
  27. console.log(tempScaler.dataToView(30));  // 125 (四分之一位置)
  28. console.log(tempScaler.viewToData(250));  // 20°C
  29. console.log(tempScaler.viewToData(125));  // 30°C
  30. // 自动计算刻度
  31. function calculateTicks(min, max, maxTicks = 10) {
  32.   const range = max - min;
  33.   const roughStep = range / (maxTicks - 1);
  34.   
  35.   // 计算合适的步长(1, 2, 5, 10, 20, 50, 100等)
  36.   const exponent = Math.floor(Math.log10(roughStep));
  37.   const fraction = roughStep / Math.pow(10, exponent);
  38.   let niceFraction;
  39.   
  40.   if (fraction < 1.5) {
  41.     niceFraction = 1;
  42.   } else if (fraction < 3) {
  43.     niceFraction = 2;
  44.   } else if (fraction < 7) {
  45.     niceFraction = 5;
  46.   } else {
  47.     niceFraction = 10;
  48.   }
  49.   
  50.   const step = niceFraction * Math.pow(10, exponent);
  51.   const niceMin = Math.floor(min / step) * step;
  52.   const niceMax = Math.ceil(max / step) * step;
  53.   
  54.   const ticks = [];
  55.   for (let tick = niceMin; tick <= niceMax; tick += step) {
  56.     ticks.push(tick);
  57.   }
  58.   
  59.   return {
  60.     min: niceMin,
  61.     max: niceMax,
  62.     step: step,
  63.     ticks: ticks
  64.   };
  65. }
  66. // 使用示例:为数据范围[3.7, 48.3]计算合适的刻度
  67. const ticks = calculateTicks(3.7, 48.3);
  68. console.log(ticks);
  69. // 输出:
  70. // {
  71. //   min: 0,
  72. //   max: 50,
  73. //   step: 10,
  74. //   ticks: [0, 10, 20, 30, 40, 50]
  75. // }
  76. // 数字格式化 - 根据数值大小自动选择单位
  77. function formatNumber(value) {
  78.   const abs = Math.abs(value);
  79.   
  80.   if (abs >= 1000000000) {
  81.     return (value / 1000000000).toFixed(1) + 'B';  // 十亿
  82.   } else if (abs >= 1000000) {
  83.     return (value / 1000000).toFixed(1) + 'M';    // 百万
  84.   } else if (abs >= 1000) {
  85.     return (value / 1000).toFixed(1) + 'K';       // 千
  86.   } else {
  87.     return value.toString();
  88.   }
  89. }
  90. console.log(formatNumber(1234));      // "1.2K"
  91. console.log(formatNumber(1234567));   // "1.2M"
  92. console.log(formatNumber(1234567890)); // "1.2B"
  93. console.log(formatNumber(-567));      // "-567"
复制代码

游戏开发中的数字计算

游戏开发中经常需要处理各种数字计算,包括物理模拟、动画和随机事件:
  1. // 向量运算(2D)
  2. class Vector2 {
  3.   constructor(x = 0, y = 0) {
  4.     this.x = x;
  5.     this.y = y;
  6.   }
  7.   
  8.   // 向量加法
  9.   add(vector) {
  10.     return new Vector2(this.x + vector.x, this.y + vector.y);
  11.   }
  12.   
  13.   // 向量减法
  14.   subtract(vector) {
  15.     return new Vector2(this.x - vector.x, this.y - vector.y);
  16.   }
  17.   
  18.   // 标量乘法
  19.   multiply(scalar) {
  20.     return new Vector2(this.x * scalar, this.y * scalar);
  21.   }
  22.   
  23.   // 向量点积
  24.   dot(vector) {
  25.     return this.x * vector.x + this.y * vector.y;
  26.   }
  27.   
  28.   // 向量长度
  29.   length() {
  30.     return Math.sqrt(this.x * this.x + this.y * this.y);
  31.   }
  32.   
  33.   // 向量归一化
  34.   normalize() {
  35.     const len = this.length();
  36.     if (len > 0) {
  37.       return new Vector2(this.x / len, this.y / len);
  38.     }
  39.     return new Vector2(0, 0);
  40.   }
  41.   
  42.   // 旋转向量
  43.   rotate(angle) {
  44.     const cos = Math.cos(angle);
  45.     const sin = Math.sin(angle);
  46.     return new Vector2(
  47.       this.x * cos - this.y * sin,
  48.       this.x * sin + this.y * cos
  49.     );
  50.   }
  51. }
  52. // 使用示例
  53. const v1 = new Vector2(3, 4);
  54. const v2 = new Vector2(1, 2);
  55. console.log(v1.add(v2));          // Vector2 { x: 4, y: 6 }
  56. console.log(v1.length());         // 5
  57. console.log(v1.normalize());      // Vector2 { x: 0.6, y: 0.8 }
  58. // 缓动函数 - 用于平滑动画
  59. const Easing = {
  60.   linear: (t) => t,
  61.   
  62.   easeInQuad: (t) => t * t,
  63.   easeOutQuad: (t) => t * (2 - t),
  64.   easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
  65.   
  66.   easeInCubic: (t) => t * t * t,
  67.   easeOutCubic: (t) => (--t) * t * t + 1,
  68.   easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
  69.   
  70.   easeInElastic: (t) => {
  71.     if (t === 0 || t === 1) return t;
  72.     const p = 0.3;
  73.     return -Math.pow(2, 10 * (t - 1)) * Math.sin((t - 1.1) * 5 * Math.PI / p);
  74.   },
  75.   easeOutElastic: (t) => {
  76.     if (t === 0 || t === 1) return t;
  77.     const p = 0.3;
  78.     return Math.pow(2, -10 * t) * Math.sin((t - 0.1) * 5 * Math.PI / p) + 1;
  79.   }
  80. };
  81. // 使用缓动函数进行动画
  82. function animateValue(start, end, duration, easingFunction = Easing.linear, callback) {
  83.   const startTime = performance.now();
  84.   
  85.   function update(currentTime) {
  86.     const elapsed = currentTime - startTime;
  87.     const progress = Math.min(elapsed / duration, 1);
  88.     const easedProgress = easingFunction(progress);
  89.     const currentValue = start + (end - start) * easedProgress;
  90.    
  91.     callback(currentValue);
  92.    
  93.     if (progress < 1) {
  94.       requestAnimationFrame(update);
  95.     }
  96.   }
  97.   
  98.   requestAnimationFrame(update);
  99. }
  100. // 使用示例:在2秒内将值从0动画到100,使用easeOutCubic缓动
  101. animateValue(0, 100, 2000, Easing.easeOutCubic, (value) => {
  102.   console.log(value.toFixed(2));
  103. });
  104. // 概率系统 - 用于游戏中的随机事件
  105. class ProbabilitySystem {
  106.   constructor() {
  107.     this.events = [];
  108.   }
  109.   
  110.   // 添加事件及其概率
  111.   addEvent(event, probability) {
  112.     this.events.push({ event, probability });
  113.     return this;
  114.   }
  115.   
  116.   // 随机选择一个事件
  117.   random() {
  118.     const totalProbability = this.events.reduce((sum, e) => sum + e.probability, 0);
  119.     let random = Math.random() * totalProbability;
  120.    
  121.     for (const event of this.events) {
  122.       random -= event.probability;
  123.       if (random <= 0) {
  124.         return event.event;
  125.       }
  126.     }
  127.    
  128.     return this.events[this.events.length - 1].event;
  129.   }
  130. }
  131. // 使用示例:创建一个战利品掉落系统
  132. const lootSystem = new ProbabilitySystem()
  133.   .addEvent("普通装备", 60)
  134.   .addEvent("稀有装备", 30)
  135.   .addEvent("史诗装备", 9)
  136.   .addEvent("传说装备", 1);
  137. // 模拟100次掉落
  138. const lootCounts = { "普通装备": 0, "稀有装备": 0, "史诗装备": 0, "传说装备": 0 };
  139. for (let i = 0; i < 100; i++) {
  140.   const loot = lootSystem.random();
  141.   lootCounts[loot]++;
  142. }
  143. console.log(lootCounts);
  144. // 输出类似于: { "普通装备": 58, "稀有装备": 32, "史诗装备": 8, "传说装备": 2 }
复制代码

金融计算中的精确数字处理

金融计算对数字精度要求极高,JavaScript的浮点数精度问题可能会导致严重错误:
  1. // 金融计算工具类
  2. class FinancialCalculator {
  3.   // 精确的加法
  4.   static add(a, b) {
  5.     const aStr = a.toString();
  6.     const bStr = b.toString();
  7.    
  8.     // 找出小数点后的最大位数
  9.     const aDecimalPlaces = aStr.includes('.') ? aStr.split('.')[1].length : 0;
  10.     const bDecimalPlaces = bStr.includes('.') ? bStr.split('.')[1].length : 0;
  11.     const maxDecimalPlaces = Math.max(aDecimalPlaces, bDecimalPlaces);
  12.    
  13.     // 转换为整数进行计算
  14.     const factor = Math.pow(10, maxDecimalPlaces);
  15.     const aInt = Math.round(a * factor);
  16.     const bInt = Math.round(b * factor);
  17.    
  18.     return (aInt + bInt) / factor;
  19.   }
  20.   
  21.   // 精确的减法
  22.   static subtract(a, b) {
  23.     const aStr = a.toString();
  24.     const bStr = b.toString();
  25.    
  26.     // 找出小数点后的最大位数
  27.     const aDecimalPlaces = aStr.includes('.') ? aStr.split('.')[1].length : 0;
  28.     const bDecimalPlaces = bStr.includes('.') ? bStr.split('.')[1].length : 0;
  29.     const maxDecimalPlaces = Math.max(aDecimalPlaces, bDecimalPlaces);
  30.    
  31.     // 转换为整数进行计算
  32.     const factor = Math.pow(10, maxDecimalPlaces);
  33.     const aInt = Math.round(a * factor);
  34.     const bInt = Math.round(b * factor);
  35.    
  36.     return (aInt - bInt) / factor;
  37.   }
  38.   
  39.   // 精确的乘法
  40.   static multiply(a, b) {
  41.     const aStr = a.toString();
  42.     const bStr = b.toString();
  43.    
  44.     // 计算小数点后的总位数
  45.     const aDecimalPlaces = aStr.includes('.') ? aStr.split('.')[1].length : 0;
  46.     const bDecimalPlaces = bStr.includes('.') ? bStr.split('.')[1].length : 0;
  47.     const totalDecimalPlaces = aDecimalPlaces + bDecimalPlaces;
  48.    
  49.     // 转换为整数进行计算
  50.     const aInt = Math.round(a * Math.pow(10, aDecimalPlaces));
  51.     const bInt = Math.round(b * Math.pow(10, bDecimalPlaces));
  52.    
  53.     return (aInt * bInt) / Math.pow(10, totalDecimalPlaces);
  54.   }
  55.   
  56.   // 精确的除法
  57.   static divide(a, b, precision = 10) {
  58.     if (b === 0) throw new Error("Division by zero");
  59.    
  60.     const aStr = a.toString();
  61.     const bStr = b.toString();
  62.    
  63.     // 计算小数点后的位数
  64.     const aDecimalPlaces = aStr.includes('.') ? aStr.split('.')[1].length : 0;
  65.     const bDecimalPlaces = bStr.includes('.') ? bStr.split('.')[1].length : 0;
  66.    
  67.     // 转换为整数进行计算
  68.     const aInt = Math.round(a * Math.pow(10, aDecimalPlaces));
  69.     const bInt = Math.round(b * Math.pow(10, bDecimalPlaces));
  70.    
  71.     // 计算结果并调整小数位数
  72.     const result = (aInt / bInt) * Math.pow(10, bDecimalPlaces - aDecimalPlaces);
  73.    
  74.     // 四舍五入到指定精度
  75.     return Math.round(result * Math.pow(10, precision)) / Math.pow(10, precision);
  76.   }
  77.   
  78.   // 计算复利
  79.   static calculateCompoundInterest(principal, rate, time, compoundFrequency = 1) {
  80.     // A = P(1 + r/n)^(nt)
  81.     // 其中 P 是本金,r 是年利率,t 是时间(年),n 是复利频率
  82.     const base = FinancialCalculator.add(1, FinancialCalculator.divide(rate, compoundFrequency));
  83.     const exponent = time * compoundFrequency;
  84.    
  85.     // 使用精确计算计算幂
  86.     let result = 1;
  87.     for (let i = 0; i < exponent; i++) {
  88.       result = FinancialCalculator.multiply(result, base);
  89.     }
  90.    
  91.     return FinancialCalculator.multiply(principal, result);
  92.   }
  93.   
  94.   // 计算贷款月供
  95.   static calculateLoanPayment(principal, annualRate, years) {
  96.     // 月利率
  97.     const monthlyRate = FinancialCalculator.divide(annualRate, 12);
  98.    
  99.     // 总月数
  100.     const totalMonths = years * 12;
  101.    
  102.     // 如果月利率为0,直接返回本金除以月数
  103.     if (monthlyRate === 0) {
  104.       return FinancialCalculator.divide(principal, totalMonths);
  105.     }
  106.    
  107.     // 计算月供:P = (r * PV) / (1 - (1 + r)^(-n))
  108.     const numerator = FinancialCalculator.multiply(monthlyRate, principal);
  109.    
  110.     // 计算(1 + r)^(-n)
  111.     const base = FinancialCalculator.add(1, monthlyRate);
  112.     let denominatorBase = 1;
  113.     for (let i = 0; i < totalMonths; i++) {
  114.       denominatorBase = FinancialCalculator.multiply(denominatorBase, base);
  115.     }
  116.     const denominator = FinancialCalculator.subtract(1, FinancialCalculator.divide(1, denominatorBase));
  117.    
  118.     return FinancialCalculator.divide(numerator, denominator);
  119.   }
  120. }
  121. // 使用示例:精确计算
  122. console.log(FinancialCalculator.add(0.1, 0.2));  // 0.3
  123. console.log(FinancialCalculator.multiply(0.1, 0.2));  // 0.02
  124. // 计算复利
  125. const principal = 1000;  // 本金1000元
  126. const rate = 0.05;       // 年利率5%
  127. const time = 10;         // 10年
  128. const compoundFrequency = 12;  // 每月复利
  129. const finalAmount = FinancialCalculator.calculateCompoundInterest(principal, rate, time, compoundFrequency);
  130. console.log(`复利计算结果: ${finalAmount.toFixed(2)}元`);
  131. // 计算贷款月供
  132. const loanPrincipal = 200000;  // 贷款20万
  133. const loanRate = 0.049;        // 年利率4.9%
  134. const loanYears = 30;          // 30年
  135. const monthlyPayment = FinancialCalculator.calculateLoanPayment(loanPrincipal, loanRate, loanYears);
  136. console.log(`贷款月供: ${monthlyPayment.toFixed(2)}元`);
  137. // 货币格式化
  138. function formatCurrency(amount, locale = 'zh-CN', currency = 'CNY') {
  139.   return new Intl.NumberFormat(locale, {
  140.     style: 'currency',
  141.     currency: currency,
  142.     minimumFractionDigits: 2
  143.   }).format(amount);
  144. }
  145. console.log(formatCurrency(finalAmount));  // 例如:"¥1,647.01"
  146. console.log(formatCurrency(monthlyPayment));  // 例如:"¥1,061.45"
复制代码

总结

JavaScript数字处理是Web开发中的基础技能,掌握各种数字处理技巧可以帮助我们更高效地解决实际问题。本指南从JavaScript数字的基础知识开始,介绍了数字类型、表示方法和特殊值,然后深入探讨了基础数学运算、数字格式化、高级数字处理技术,以及在实际开发中的应用场景。

我们学习了如何处理JavaScript中的浮点数精度问题,如何使用BigInt处理大整数,以及如何进行精确的金融计算。我们还探讨了数字范围限制、验证和性能优化等实用技巧,并通过数据可视化、游戏开发和金融计算等实际应用场景,展示了这些技术的实际应用。

通过掌握这些数字处理技巧,你将能够更加自信地处理JavaScript中的各种数字计算任务,避免常见的陷阱,提高代码的准确性和性能。无论你是初学者还是有经验的开发者,这些知识都将对你的开发工作有所帮助。

希望本指南能够成为你在JavaScript数字处理方面的宝贵资源,帮助你在日常开发中更加高效地解决数字相关的问题。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

手机版|联系我们|小黑屋|TG频道|RSS |网站地图

Powered by Pixtech

© 2025-2026 Pixtech Team.

>