JavaScript系列(4)--数值类型专题
JavaScript数值类型专题 🔢
在前三篇文章中,我们探讨了JavaScript的语言特性、ECMAScript标准和引擎工作原理。今天,让我们深入了解JavaScript中的数值类型。这个看似简单的主题实际上蕴含着许多有趣的细节和需要注意的要点。
数值类型概述 🌟
💡 小知识:JavaScript中所有的数字都是以64位浮点数(IEEE 754)格式存储的,这种统一的表示方式既带来了便利,也带来了一些特殊的行为。
数值的内部表示 📊
JavaScript中的数值是如何在内存中存储的:
// 1. 数值的基本表示
function numberRepresentation() {
// 整数
const integer = 42;
console.log(integer.toString(2)); // 二进制表示:101010
// 浮点数
const float = 3.14;
console.log(float.toString(2)); // 二进制表示:11.001001000111...
// 科学记数法
const scientific = 1.23e-4; // 0.000123
console.log(scientific.toFixed(6)); // "0.000123"
// 特殊值
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
console.log(Number.EPSILON); // 2.220446049250313e-16
}
// 2. 数值精度问题
function precisionIssues() {
// 浮点数计算精度问题
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false
// 安全的整数运算
console.log(Number.isSafeInteger(9007199254740991)); // true
console.log(Number.isSafeInteger(9007199254740992)); // false
// 处理精度问题的方法
function safeAdd(a, b) {
// 转换为整数计算
const factor = 1000000;
return (a * factor + b * factor) / factor;
}
console.log(safeAdd(0.1, 0.2)); // 0.3
}
// 3. 数值的边界情况
function numberBoundaries() {
// Infinity和-Infinity
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(Infinity > Number.MAX_VALUE); // true
// NaN(Not a Number)
console.log(0 / 0); // NaN
console.log(parseInt('abc')); // NaN
console.log(NaN === NaN); // false
console.log(Number.isNaN(NaN)); // true
// 零的符号
console.log(0 === -0); // true
console.log(1 / 0); // Infinity
console.log(1 / -0); // -Infinity
console.log(Object.is(0, -0)); // false
}
数值转换和格式化 🔄
JavaScript提供了多种方式来转换和格式化数值:
// 1. 数值转换
function numberConversion() {
// 字符串转数值
console.log(Number('123')); // 123
console.log(parseInt('123abc')); // 123
console.log(parseFloat('3.14')); // 3.14
console.log(+'123'); // 123
// 不同进制的转换
console.log(parseInt('1010', 2)); // 10 (二进制转十进制)
console.log(parseInt('ff', 16)); // 255 (十六进制转十进制)
console.log((255).toString(16)); // "ff" (十进制转十六进制)
// 数值格式化
const num = 3.14159;
console.log(num.toFixed(2)); // "3.14"
console.log(num.toPrecision(3)); // "3.14"
console.log(num.toExponential(2)); // "3.14e+0"
}
// 2. 本地化格式
function numberLocalization() {
const number = 1234567.89;
// 使用不同的地区格式
console.log(number.toLocaleString('en-US')); // "1,234,567.89"
console.log(number.toLocaleString('de-DE')); // "1.234.567,89"
console.log(number.toLocaleString('zh-CN')); // "1,234,567.89"
// 货币格式化
const options = { style: 'currency', currency: 'USD' };
console.log(number.toLocaleString('en-US', options)); // "$1,234,567.89"
console.log(number.toLocaleString('de-DE', options)); // "1.234.567,89 $"
console.log(number.toLocaleString('zh-CN', options)); // "US$1,234,567.89"
}
// 3. 自定义格式化
function customFormatting() {
// 添加千位分隔符
function addThousandsSeparator(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
console.log(addThousandsSeparator(1234567)); // "1,234,567"
// 格式化为指定小数位数
function formatDecimal(num, places) {
return Number(Math.round(num + 'e' + places) + 'e-' + places);
}
console.log(formatDecimal(3.14159, 2)); // 3.14
}
数学运算和计算 ➗
JavaScript提供了丰富的数学运算功能:
// 1. 基本数学运算
function basicMath() {
// 四则运算
console.log(10 + 5); // 15
console.log(10 - 5); // 5
console.log(10 * 5); // 50
console.log(10 / 5); // 2
// 取模和幂运算
console.log(10 % 3); // 1
console.log(2 ** 3); // 8
// 自增和自减
let num = 5;
console.log(num++); // 5 (返回后增加)
console.log(++num); // 7 (增加后返回)
}
// 2. Math对象方法
function mathObjectMethods() {
// 取整方法
console.log(Math.floor(3.7)); // 3
console.log(Math.ceil(3.2)); // 4
console.log(Math.round(3.5)); // 4
console.log(Math.trunc(3.7)); // 3
// 最值
console.log(Math.max(1, 5, 3)); // 5
console.log(Math.min(1, 5, 3)); // 1
// 随机数
console.log(Math.random()); // 0到1之间的随机数
// 三角函数
console.log(Math.sin(Math.PI / 2));// 1
console.log(Math.cos(Math.PI)); // -1
console.log(Math.tan(Math.PI / 4));// 1
}
// 3. 高精度计算
class DecimalCalculator {
constructor(precision = 10) {
this.precision = precision;
this.multiplier = 10 ** precision;
}
add(a, b) {
const result = this._toInteger(a) + this._toInteger(b);
return result / this.multiplier;
}
subtract(a, b) {
const result = this._toInteger(a) - this._toInteger(b);
return result / this.multiplier;
}
multiply(a, b) {
const result = this._toInteger(a) * this._toInteger(b);
return result / (this.multiplier * this.multiplier);
}
divide(a, b) {
if (b === 0) throw new Error('除数不能为0');
const result = (this._toInteger(a) * this.multiplier) / this._toInteger(b);
return result;
}
_toInteger(num) {
return Math.round(num * this.multiplier);
}
}
// 使用高精度计算器
const calculator = new DecimalCalculator(2);
console.log(calculator.add(0.1, 0.2)); // 0.3
console.log(calculator.multiply(0.1, 0.2)); // 0.02
数值类型的应用场景 💼
让我们看看数值类型在实际应用中的一些场景:
// 1. 金融计算
class FinancialCalculator {
// 计算复利
static compoundInterest(principal, rate, years) {
return principal * Math.pow(1 + rate, years);
}
// 计算贷款每月还款额
static monthlyPayment(principal, annualRate, years) {
const monthlyRate = annualRate / 12;
const numberOfPayments = years * 12;
return principal * monthlyRate * Math.pow(1 + monthlyRate, numberOfPayments)
/ (Math.pow(1 + monthlyRate, numberOfPayments) - 1);
}
// 计算折现现值
static presentValue(futureValue, rate, years) {
return futureValue / Math.pow(1 + rate, years);
}
}
// 2. 统计计算
class StatisticsCalculator {
// 计算平均值
static mean(numbers) {
return numbers.reduce((sum, num) => sum + num, 0) / numbers.length;
}
// 计算中位数
static median(numbers) {
const sorted = [...numbers].sort((a, b) => a - b);
const middle = Math.floor(sorted.length / 2);
if (sorted.length % 2 === 0) {
return (sorted[middle - 1] + sorted[middle]) / 2;
}
return sorted[middle];
}
// 计算标准差
static standardDeviation(numbers) {
const mean = this.mean(numbers);
const squareDiffs = numbers.map(num => Math.pow(num - mean, 2));
return Math.sqrt(this.mean(squareDiffs));
}
}
// 3. 图形计算
class GeometryCalculator {
// 计算圆的面积
static circleArea(radius) {
return Math.PI * radius * radius;
}
// 计算三角形面积
static triangleArea(base, height) {
return (base * height) / 2;
}
// 计算两点之间的距离
static distance(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
// 计算角度
static toDegrees(radians) {
return radians * (180 / Math.PI);
}
static toRadians(degrees) {
return degrees * (Math.PI / 180);
}
}
性能优化技巧 🚀
在处理数值计算时,有一些性能优化的技巧:
// 1. 位运算优化
function bitOperations() {
// 使用位运算取整
console.log(~~3.7); // 3
console.log(3.7 | 0); // 3
// 使用位运算判断奇偶
function isEven(num) {
return (num & 1) === 0;
}
// 使用位运算乘除2
console.log(8 << 1); // 16 (乘2)
console.log(8 >> 1); // 4 (除2)
}
// 2. 缓存计算结果
class MathCache {
constructor() {
this.cache = new Map();
}
// 计算并缓存结果
calculate(operation, ...args) {
const key = `${operation}-${args.join(',')}`;
if (!this.cache.has(key)) {
const result = this._performCalculation(operation, ...args);
this.cache.set(key, result);
}
return this.cache.get(key);
}
_performCalculation(operation, ...args) {
switch (operation) {
case 'power':
return Math.pow(...args);
case 'sqrt':
return Math.sqrt(args[0]);
// 添加更多运算...
default:
throw new Error('未知的运算');
}
}
}
// 3. 批量计算优化
function batchCalculations() {
// 使用TypedArray进行批量计算
const numbers = new Float64Array(1000000);
// 填充数据
for (let i = 0; i < numbers.length; i++) {
numbers[i] = Math.random();
}
// 批量计算平方根
const results = new Float64Array(numbers.length);
for (let i = 0; i < numbers.length; i++) {
results[i] = Math.sqrt(numbers[i]);
}
}
最佳实践建议 💡
- 处理精度问题
// 1. 使用整数运算
function moneyCalculation(amount1, amount2) {
// 转换为分进行计算
const cents1 = Math.round(amount1 * 100);
const cents2 = Math.round(amount2 * 100);
return (cents1 + cents2) / 100;
}
// 2. 使用toFixed进行显示
function formatMoney(amount) {
return Number(amount.toFixed(2));
}
// 3. 比较浮点数
function approximatelyEqual(n1, n2, epsilon = 0.0001) {
return Math.abs(n1 - n2) < epsilon;
}
- 数值验证和安全性
// 1. 验证是否为有效数字
function isValidNumber(value) {
return typeof value === 'number' &&
!isNaN(value) &&
isFinite(value);
}
// 2. 安全的数值转换
function safeParseInt(value, base = 10) {
const result = parseInt(value, base);
return isNaN(result) ? 0 : result;
}
// 3. 范围限制
function clamp(num, min, max) {
return Math.min(Math.max(num, min), max);
}
结语 📝
JavaScript的数值类型虽然看似简单,但要正确处理各种场景还是需要深入的理解。我们学习了:
- 数值的内部表示和精度问题
- 数值转换和格式化方法
- 数学运算和计算技巧
- 实际应用场景
- 性能优化和最佳实践
💡 学习建议:在处理金融计算时,务必注意精度问题,可以考虑使用专门的库(如decimal.js)来处理高精度计算。
如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇
终身学习,共同成长。
咱们下一期见
💻