JavaScript开发:使用Number数据类型需要注意的问题

本文以《JavaScript高级程序设计》第4版作为参考,整理使用JavaScript开发过程中,使用Number数据类型相关的知识点。

本文是开发知识点系列第三篇。

  1. 第一篇:JavaScript开发中变量、常量声明的规矩总结
  2. 第二篇:JavaScript开发:数据类型知识总结

初始化规则

最基本的数值字面量格式是十进制整数,直接写出来即可。也可以写八进制或者十六进制字面量。

要定义浮点值,数值中必须包含小数点,而且小数点后面必须至少有一个数字。

数值转换规则

有三个函数可以将非数值转为数值:Number()parseInt()parseFloat()。Number可以用于任何数据类型。后两个函数主要用于将字符串转为数值。

parseInt()会将truefalsenullundefined、''转为NaNparseFloat()同样如此。

js 复制代码
console.log(parseInt(true))  // NaN
console.log(parseInt(false)) // NaN
console.log(parseInt(null))  // NaN
console.log(parseInt(undefined)) // NaN
console.log(parseInt('')) // NaN


console.log(parseFloat(true))  // NaN
console.log(parseFloat(false)) // NaN
console.log(parseFloat(null))  // NaN
console.log(parseFloat(undefined)) // NaN
console.log(parseFloat('')) // NaN

而number()转换规则

js 复制代码
console.log(Number(true))  // 1
console.log(Number(false)) // 0
console.log(Number(null))  // 0
console.log(Number(undefined)) // undefined
console.log(Number('')) // 0

是否符合你的预想?

另外parseFloat()只解析十进制值,这点和parseInt()是不一样的。

parseInt()转换字符串的一般规则

js 复制代码
parseInt('123abc'); // 123
parseInt('abc123'); // NaN
parseInt('0x123'); // 291
parseInt('011'); // 11
parseInt('011', 8); // 9
parseInt('11', 2); // 3
parseInt('-1') // -1
parseInt('+1') // 1

parseFloat()转换字符串

js 复制代码
parseFloat('123.456abc'); // 123.456
parseFloat('123.45.6abc'); // 123.45
parseFloat('abc123'); // NaN
parseFloat('0x123'); // 0
parseFloat('123e-2'); // 1.2

NaN

NaN属于Number数据类型,意思是不是数值(Not a Number),NaN是唯一不等于自身的数据。任何涉及NaN的操作始终是返回NaN。

js 复制代码
console.log(NaN === NaN, NaN == NaN) // false false

判断数据是否为NaN,可以使用isNaN()

大数相加问题

通过转换解决

在JavaScript中,当需要处理大数相加问题时,可以使用字符串或数组来表示大数,并编写算法来模拟手动相加的过程。以下是一种常见的解决方案:

  1. 将大数转换为字符串或数组:将大数转换为字符串或数组,其中每个元素表示大数的一位数字。例如,将大数 123456789 转换为字符串 "123456789" 或数组 [1, 2, 3, 4, 5, 6, 7, 8, 9]

  2. 实现手动相加算法:从大数的最低位开始,逐位相加,并考虑进位。可以使用循环或递归来实现这个算法。例如,从最低位开始,将对应位的数字相加,并将结果存储在结果数组或字符串中。如果有进位,则将进位加到下一位的相加结果中。

  3. 处理边界情况:在相加过程中,需要考虑两个大数的位数不一致的情况。可以在算法中处理这种情况,确保两个大数的每一位都参与相加。

以下是一个使用字符串表示大数的示例代码:

js 复制代码
function addBigNumbers(num1, num2) {
  let result = "";
  let carry = 0;
  let i = num1.length - 1;
  let j = num2.length - 1;

  while (i >= 0 || j >= 0 || carry > 0) {
    const digit1 = i >= 0 ? parseInt(num1[i]) : 0;
    const digit2 = j >= 0 ? parseInt(num2[j]) : 0;
    const sum = digit1 + digit2 + carry;
    const digitSum = sum % 10;
    carry = Math.floor(sum / 10);

    result = digitSum + result;

    i--;
    j--;
  }

  return result;
}

const num1 = "123456789";
const num2 = "987654321";
const sum = addBigNumbers(num1, num2);
console.log(sum); // 输出:1111111110

通过以上方法,可以解决JavaScript中的大数相加问题。需要注意的是,这种方法适用于处理较大的数,但对于非常大的数,可能会超出JavaScrip 数字类型的精度范围。在实际应用中,可能需要使用专门的大数库或其他算法来处理更大的数。

BigInt

JavaScript中的BigInt类型可以用于处理大数相加问题。BigInt是ES2020中引入的一种数据类型,用于表示任意精度的整数。 使用BigInt,可以直接进行大数相加操作,而无需担心数值溢出或精度问题。以下是使用BigInt进行大数相加的示例:

js 复制代码
const num1 = BigInt("123456789");
const num2 = BigInt("987654321");
const sum = num1 + num2;
console.log(sum.toString()); // 输出:111111111

需要注意的是使用BigInt需要考虑浏览器兼容性问题。

0.1 + 0.2 === 0.3问题

在 JavaScript 中,由于浮点数的精度问题,0.1 + 0.2 的结果并不精确等于 0.3。这是由于浮点数的二进制表示方式导致的舍入误差。

为了在JavaScript中进行浮点数的比较,可以使用以下方法:

  1. 使用误差范围:使用一个非常小的误差范围来比较两个浮点数是否接近。例如,可以使用以下代码来比较 0.1 + 0.2 是否接近于 0.3:
js 复制代码
const result = 0.1 + 0.2;
const target = 0.3;
const epsilon = 0.000001; // 误差范围

if (Math.abs(result - target) < epsilon) {
  console.log("0.1 + 0.2 is approximately equal to 0.3");
} else {
  console.log("0.1 + 0.2 is not equal to 0.3");
}
  1. 使用整数运算:如果需要精确的小数运算,可以将小数转换为整数进行运算,然后再将结果转换回小数。例如,可以将 0.1 和 0.2 乘以一个倍数,进行整数运算,然后再除以相同的倍数,得到精确的结果。
js 复制代码
const result = (0.1 * 10 + 0.2 * 10) / 10;
const target = 0.3;

if (result === target) {
  console.log("0.1 + 0.2 is equal to 0.3");
} else {
  console.log("0.1 + 0.2 is not equal to 0.3");
}

需要注意的是,这些方法都是通过近似比较来判断浮点数的相等性,而不是精确比较。在进行浮点数比较时,应根据具体需求和精度要求来选择合适的方法。

toFixed精度问题

toFixed() 方法在处理小数位数时可能会出现一些精度问题。这是因为JavaScript中的数字是基于 IEEE 754 浮点数标准表示的,而不是精确的十进制数。

要解决 toFixed() 方法的精度问题,可以使用以下方法:

  1. 扩大倍数后取整:将要处理的数字乘以一个倍数,然后使用 Math.round()Math.floor()Math.ceil() 方法将结果取整,最后再除以相同的倍数。这样可以避免直接使用 toFixed() 方法的精度问题。
javascript 复制代码
const num = 0.1 + 0.2;
const fixedNum = Math.round(num * 100) / 100;
console.log(fixedNum); // 输出:0.3
  1. 使用字符串操作:将数字转换为字符串,然后使用字符串的操作方法来处理小数位数。例如,可以使用正则表达式或字符串的截取方法来控制小数位数。
javascript 复制代码
const num = 0.1 + 0.2;
const fixedNum = parseFloat(num.toFixed(15)).toString(); // 保留 15 位小数
console.log(fixedNum); // 输出:0.3

需要根据具体的需求和场景选择合适的方法来解决 toFixed() 方法的精度问题。这些方法可以提供更好的精度控制,但仍需要注意 JavaScript 浮点数的精度限制。

本文完。

相关推荐
涔溪41 分钟前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞1 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与1 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun1 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇1 小时前
ES6进阶知识一
前端·ecmascript·es6
前端郭德纲1 小时前
浏览器是加载ES6模块的?
javascript·算法
JerryXZR1 小时前
JavaScript核心编程 - 原型链 作用域 与 执行上下文
开发语言·javascript·原型模式
帅帅哥的兜兜1 小时前
CSS:导航栏三角箭头
javascript·css3
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss