JS-Number数字类型详解

一、前言

与其他语言不同,在JS中不区分整数与浮点数,统一为浮点数。所有数字类型统一都是基于 IEEE 754 标准来实现;采用的是“双精度”格式(即 64 位二进制)。这也意味着在小数计算时,会发生精度误差的情况(这并不是js独有的,其他基于IEEE 754标准的都会有这样的问题)。

二、属性方法

2.1 定义数字类型

JS中的数字常量一般用十进制表示。例如:

const a = 42;
const b = 42.3;

数字前后的 0 可以省略:(不建议,请规范写法)

const a = 0.42;
const b = .42;
const c = 42.0;
const d = 42.;

数字常量还可以用其他格式来表示,八进制和十六进制;如果前缀为 0,则 JavaScript 会把数值常量解释为八进制数,如果前缀为 0 和 “x”,则解释为十六进制数。例如:

const a = 070;
const b = 0xFF;

2.2 特殊的数值

2.2.1 最大值:Number.MAX_SAFE_INTEGER

最大整数是 2^53 - 1,即 9007199254740991,在 ES6 中被定义为Number.MAX_SAFE_INTEGER。

2.2.2 最小值:Number.MIN_SAFE_INTEGER

最小整数是 -9007199254740991,在 ES6 中被定义为 Number.MIN_SAFE_INTEGER。

2.2.3 无穷数

在进行运算时,可能都遇到过编译错误或者运行时错误,例如“除以 0”。这个时候不会得到无穷数,正无穷Infinity(Number.POSITIVE_INFINITY)与负无穷-Infinity(Number.NEGATIVE_INFINITY)。

2.2.4 不是数字的数字:NaN

如果数学运算的操作数不是数字类型(或者无法解析为常规的十进制或十六进制数字),就无法返回一个有效的数字,这种情况下返回值为 NaN。可以通过Number.isNaN(值)判断。

const a = 2 / "测试"; // NaN
a == NaN; // false
a === NaN; // false
Number.isNaN(a); // true

注意:在运算的时候要注意避免得到NaN,防止程序出现错误;

2.2.5 零值

JavaScript 有一个常规的 0(也叫作+0)和一个 -0。-0 除了可以用作常量以外,也可以是某些数学运算的返回值。

const a = 0 / -2; // -0
const b = 0 * -2; // -0
//  但是规范定义的返回结果是这样
a.toString(); // "0"
a + ""; // "0"
String( a ); // "0"
// 但是-0字符串翻过来就是对的
+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0
// 0与-0比较都为true
-0 == 0; // true
-0 === 0; // true

注意:需要注意正负0的比较,使用-0场景例如动画帧的移动速度等。

2.3 数字的方法

  1. toSting:以字符串返回数值
  2. toFixed:返回字符串值,它包含了指定位数小数的数字(会四舍五入)
  3. toPrecision: 返回字符串值,它包含了指定长度的数字
const a = 22;
a.toString(); // '22'
a.toFixed(3); // '22.000'
const b = 2.222;
b.toPrecision(2); // '2.2'
b.toPrecision(3); // '2.22'

2.4 变量转换为数字

  1. Number:将变量转换为数字
  2. parseInt:返回数字的整数部分
  3. parseFloat:返回一个浮点数
Number('22.2'); // 22.2
parseInt('22.2'); // 22
parseFloat('22.2'); // 22.2
Number('测试'); // NaN
parseInt('测试'); // NaN
parseFloat('测试'); // NaN

注意:上述三个方法转换时,如果转换失败会返回NaN,开发中要注意避免。

三、实战示例

3.1 浮点数计算出现精度缺失

3.1.1 发现问题

在日常项目中会遇到小数之间的算术运算,例如商品价格的计算、账户金额的统计;涉及的小数时有时候会出现精度误差计算结果不准确,导致客户反馈bug。

示例:

console.log(0.1 + 0.2); // 0.30000000000000004
3.1.2 问题原因

我们在上面有介绍过在JS中所有数字都是以IEEE-754标准格式64位浮点数形式储存,1与1.0是相同的。因为有些小数以二进制表示位数是无穷的。JavaScript会把超出53位之后的二进制舍弃。所以并不是JS中才会出现,所有基于IEEE-754标准的浮点数计算都会有这样的问题。

3.1.3 解决方案

使用第三方类库

如果在项目中多处都需要使用浮点数计算,这个时候就需要考虑引用第三方类库方法来进行小数点之间的计算。这里推荐第三方类库:

  1. Math.js
  2. decimal.js
  3. big.js

简易封装

如果只是单纯处理个别计算问题时,可以使用下面简易封装的简易加法运算。核心思路就是:计算小数点后最大有几位,转换成10的指数幂进行计算,最后还原。

/**
 * 精度相加
 */
const addTogether = (n1, n2) => {
  let res1 = n1.toString().split(".")[1]
    ? n1.toString().split(".")[1].length
    : n1.toString().split(".")[0].length;
  let res2 = n2.toString().split(".")[1]
    ? n2.toString().split(".")[1].length
    : n2.toString().split(".")[0].length;
  let pow = Math.max(res1, res2);
  let base = Math.pow(10, pow);
  return (n1 * base + n2 * base) / base;
};

3.2 计算出现NaN

3.2.1 发现问题

在项目中设计到表单输入时,有时候会进行两个变量之间的计算,有时候展示结果会出现NaN的情况。

3.2.2 问题原因

在进行算术运算时,会将变量类型隐式转换为数字类型;如果转换原类型不是字符串的数字时无法转换为数字,就会返回NaN

3.2.3 解决方案

涉及到表单问题时要设置输入框为number类型,在计算之前需要提前转换为Number类型,如果转换为NAN要及时报错或者根据业务需求兼容处理。

const num = "测试";
const curNum = Number.isNaN(Number(num)) ? 0 : Number(num);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值