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 浮点数的精度限制。

本文完。

相关推荐
WeiXiao_Hyy16 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡33 分钟前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone39 分钟前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king2 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵3 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星3 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js