JS 主要数值类型 Number 用于表示整数和近似实数。
在 JS 代码中,像 37 这样的数字字面量是浮点数值,而不是整数。JS还有一个 BigInt 类型,但它并不是为了取代 Number 而设计的,37 仍然是一个数字,而不是一个 BigInt。
JS最大能表示的数字±1.7976931348623157e+308,最小整数:5e-324。 因为JS 使用 IEEE 754 标准定义的 64 位浮点格式表示数值。
JS不丢失精度整数范围:-2^53 + 1 到 2^53 - 1(实际范围是-2^53 到 2^53),可通过Number.MIN_SAFE_INTEGER 和Number.MAX_SAFE_INTEGER 获得。
JS某些操作是以 32 位整数计算。例如当进行位运算时,JavaScript会将数字转换为32位整数,然后进行位运算。这种转换可能会导致精度损失,因为32位整数只能表示从-2^31 到 2^31-1的范围,此外,JavaScript中的某些数学函数,如Math.pow()和Math.sqrt(),也会使用32位整数进行计算。这可能会导致精度损失,尤其是在处理大整数或小数时。
参考: MDN Number
// JS最大能表示的数字
console.log(Number.MAX_VALUE); //1.7976931348623157e+308
console.log(Number.MIN_VALUE); //5e-324
console.log(1.9976931348623157e+308); //Infinity
// JS不丢失精度整数范围
console.log(Number.MIN_SAFE_INTEGER); //-9007199254740991
console.log(Number.MAX_SAFE_INTEGER); //9007199254740991
console.log(9007199254740992); //9007199254740992
console.log(9007199254740993); //9007199254740992
二进制 前缀 0b(或0B)0b10101 // => 21: (1*16 +0*8 + 1*4+ 1*1)
八进制 前缀 0o (或0O) 0o377 // => 255: (3*64 + 7*8 + 7*1)
十进制 无前缀
十六进制 前缀 0x(或0X)。十六进制数字是数字0到9和字母a(或A )f到(或 F),表示10到15。
0xff //=> 255: (15*16 + 15)
0xBADCAFE //=> 195939070
就是小数。包含整数、小数点、小数部分
指数表示法:1.4738223E-32 // 1.4738223 * 10^-32
可以用下划线将数值字面分隔为容易看清的数字段:
let b = 1_000_000_000; // 下划线作为千分位分隔符
let bytes = 0x89_AB_CD_EF; // 作为半字节分隔符
let bits = 0b0001_1101_0111; // 作为 字节分隔符
let f = 0.123_456_789; // 也可以用在小数部分
‘+’、‘-’、‘*’、‘/’、‘%’、'’
取模(除法后的余数)%,取幂’**’
JS提供了复杂了计算Math:
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math
溢出和被0除说明
①上溢出**:超过某个数绝对值最大表示值,JS返回Infinity或-Infinity。
②下溢出:某个数值的结果比最小可表示数值更接近0的情况,此时JS返回0或者-0。0和-0几乎无法区分。
// 区分0和-0方法
let zero = 0;
let negz = -0;
zero === negz; //=> true:零等于负零
1/zero === 1/negz //=> false: Infinity 不等于 -Infinity
③被0除:被零除在 JavaScript 中不是错误,只会简单地返回无穷或负无穷。
不过有一个例外:0除以0是没有意义的值,这个操作的结果是一个特殊的“非数值”(NaN)。此外,无穷除无穷、负数平方根或者用无法转换为数值的非数值作为算术操作符的操作数,结果也都是NaN。
JavaScript预定义了全局常量Infinity和NaN以对应正无穷和非数值。这些值也可以通过Nunber对象的属性获取:
==NAN有一个特殊特性,它与任何值比较都不相等,包括他自己,==所以可以用x!==x
来判定是否是NAN。
当然还可以用isNaN()
与Number.isNaN()
。推荐使用Number.isNaN(),它更可靠
//两者是有区别的,isNaN()先转换类型,Number.isNaN()不转换类型,isNaN()字符串返回true,Number.isNaN()返回false,。
isNaN('TEST') //TRUE
isNaN('123') //FALSE
Number.isNaN(NaN) //TRUE
Number.isNaN('NaN') //FALSE
还可以用isFinite()
,isFinite 方法检测它参数的数值。如果参数是 NaN,正无穷大或者负无穷大,会返回false,其他返回 true。
isFinite(Infinity); // false
isFinite(NaN); // false
isFinite(-Infinity); // false
isFinite(0); // true
isFinite(2e64); // true,在更强壮的 Number.isFinite(null) 中将会得到false
isFinite("0"); // true,在更强壮的 Number.isFinite('0') 中将会得到 false
原因:
JS(以及所有现代编程语言) 使用的IEEE-754 浮点表示法是一种二进制表示法这种表示法可以精确地表示如 1/2、1/8 和 1/1024 等分数。然而,我们最常用的分数(特别是在进行财务计算时)是十进制分数:1/10、1/100,等等。二进制浮点表示法无法精确表示哪怕0.1这么简单的数。
虽然JavaScript 数值有足够大的精度,能够非常近似地表示 0.1,但无法精确地表示。
let x=.3-.2;
let y=.2-.1;
x === y // 两值不相等
x === .1 // false
y === .1 // true
解决方案:
①为了解决计算精度问题,你可以考虑使用等量整数。
注意这里使用等量整数,当成字符串去掉小数点,而不是简单相乘,例如console.log(79.99*100);//7998.999999999999
//两数相乘,如果需要多数相加减乘除,需要更完善封装
function accMul(arg1, arg2) {
if (arg1 && arg2) {
let m = 0,
s1 = arg1.toString(),
s2 = arg2.toString();
try {
m += s1.split(".")[1].length;
} catch (e) {}
try {
m += s2.split(".")[1].length;
} catch (e) {}
return (
(Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) /
Math.pow(10, m)
);
} else {
return undefined;
}
}
②或者使用math.js或者Decimal.js等计算库。
参考链接:https://blog.csdn.net/qq_21386275/article/details/129423569?spm=1001.2014.3001.5501
定义:
BigInt 是一种内置对象,它提供了一种方法来表示大于 2^53 - 1 的整数。这原本是 Javascript 中可以用 Number 表示的最大数字。BigInt 可以表示任意大的整数。(不过, Biglnt 的实现并不适合加密,因为它们没有考虑防止时序攻击)
描述:
可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数 BigInt(),并传递一个整数值或字符串值。
const a = 9007199254740991n; // 默认10进制
const b = BigInt(9007199254740991); // 9007199254740991n
const c = BigInt("9007199254740991"); // 9007199254740991n,传字符串
const d = BigInt("0x1fffffff"); // 536870911n,16进制
const e = BigInt("0b11111");// 31n,二进制
const f = BigInt(0o727727);// 241623n,八进制
注意点:
①不能用于 Math 对象中的方法
②不能和任何 Number 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度
③"/"该操作符结果会向零取整,也就是说不会返回小数部分。5n / 2n;//2n
④BigInt 和 Number 不是严格相等的,但是宽松相等的。0==0n // true
⑤Number 和 BigInt 可以进行比较。1n < 2;//true
⑥可以与Number混合在一个数组内进行排序
const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
mixed.sort(); // ? [-12n, 0, 0n, 10, 4n, 4, 6]
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/BigInt
创建一个新Date对象的唯一方法是通过new 操作符,例如:let now = new Date();
若将它作为常规函数调用(即不加 new 操作符),将返回一个字符串,而非 Date 对象。
console.log(Date.now()); // 不加new,返回自 1970-1-1 00:00:00 UTC(世界标准时间)至今所经过的毫秒数。即时间戳
let now = new Date(); // 当前时间的日期对象
let ms = now.getTime(); // 转换为毫秒时间戳
let iso = now.toISOString(); //转换为标准格式的字符串
参考链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/now