数值(Number,Math, 运算符)
1.js中数字
1.数字存储
Javascript中所有数字的存储都是64位浮点数。整数也一样。
1 === 1.0 // true
2. 数字大小范围
可以表示的最大正数和最小负数
(-Math.pow(2, 1024), Math.pow(2,1024)) // 开区间 // 等同于 -Number.MAX_VALUE ~ Number.MAX_VALUE // -(2**1023)*1.9999999999999998 ~ (2**1023)*1.9999999999999998
// 如果等于Math.pow(2,1024),正向溢出Infinity
Number.POSITIVE_INFINITY
// 如果-Math.pow(2, 1024)
Number.NEGATIVE_INFINITY
小数的最小取值,即可以取到的最小的正数
Math.pow(2, -1074); // 5e-324 // 还可以表示为 Number.MIN_VALUE // 5e-324 Math.pow(2, -1075); // 0 // 指数大于-1075的可以计算,<=1075"负向溢出",等于0
3. 数字精度
js中64位存储位,有52位用于精度,加上默认的1,一共53位用于表示精度。
可以表示的正负数的精度大小:
-Math.pow(2, 53) ~ Math.pow(2, 53); // 开区间;(-9007199254740992, 9007199254740992), // 也可以表示成闭区间 [-Math.pow(2, 53)+1, Math.pow(2, 53)-1], // 即[-9007199254740991, 9007199254740991] // 可以表示成-Number.MAX_SAFE_INTEGER~ Number.MAX_SAFE_INTEGER
由上面可知,精度最大是16位的十进制数,超过16位的十进制数就会失去精度。
4. 科学计数法
js在下面两种情况下,会将数字自动转为科学技术法表示:
1)数字大小超过21位
100000000000000000000 // 21位 1000000000000000000000 // 22位,1e+21
2)小数点后的0超过5位,小数点前也是0
0.000001 // 0.000001 0.0000001 // 1e-7
之所以要注意科学计数法的原因是,有的时候在运算中,js自动进行类型转换,会导致意外结果。
比如5中使用解析函数,parseInt等
5. 字符串解析成数字
Number.parseInt(str[, N进制数])--字符串解析成十进制整数
功能和parseInt一样;但是最好使用Number.parseInt(),代码模块化
将N(2-36)进制的字符串转为十进制的正数,如果第一个参数不是字符串,先转为字符串
Number.parseInt(0.0000003); // 3 // 这个属于科学计数法的第二种情况,js自动转为3e-7, 函数将其转为'3e-7' // 等同于 Number.parseInt('3e-7'); //3 只解析数字的部分 Number.parseInt(''); // NaN Number.parseInt(12.45); // 12 Number.parseInt('12ddd'); //12
其他进制转十进制
Number.parseInt(22.45); // 22 Number.parseInt(22.45, 2); // NaN, 无效的二进制数 Number.parseInt(22.45, 8); // 18, 将8进制的22转为十进制
Number.parseFloat(str) --- 将字符串转为浮点数
有几个特殊值需要注意
Number.parseFloat(''); // NaN Number('') === 0 Number.parseFloat(null); // NaN Number(null) === 0 Number.parseFloat([]); // NaN Number([]) === 0 // undefined时,和Number()相同 Number.parseFloat(undefined);// NaN Number.parseFloat(true); // NaN Number(true) === 1 Number.parseFloat('12.45f'); // 12.45 区别于Number('12.45f') ===NaN
6. 特殊数值
1. NaN
NaN不等于自身;但是Object.is中相等;
Object.is(NaN, NaN); //true NaN === NaN; // false
一些特殊值之间运算后NaN
5-'x'; // NaN 0/0; //NaN 0*Infinity; // NaN null*Infinity; // NaN 相当于0*Infinity Infinity-Infinity; //NaN Infinity/Infinity; //NaN undefined+Infinity; //NaN 相当于 NaN + Infinity
NaN和任意值的运算结果都是NaN
2.+0和-0
两者相等,有两种特殊情况
// 1)在Object.is()中不相等 Object.is(+0, -0); // false // 2) 非零值除 9/0 ;// Infinity 9/-0; // -Infinity
2. Number对象
既是构造函数,还可以作为工具函数。
1. 静态方法
1. Number.isNaN(param)/isNaN(param)---判断是否NaN
两者的区别是,前者先判断参数类型,类型不是NaN,直接返回false,不会进行转化;
isNaN会先将参数转为数值,然后再判断
Number.isNaN('d'); //false isNaN('d'); // true
2.Number.isFinite(param)/isFinite(param) --判断值是否有限
除了Infinity, -Infinity, NaN, undefined,其他的数值全部返回true;
区别:前者先判断值类型,值类型不是number,直接返回false;
后者如果不是数值类型,先转化为数值类型
Number.isFinite('12'); // false isFinite('12'); // true
3.Number.parseInt()/ Number.parseFloat()
4.Number.isInteger(number)--判断一个值是否是整数
先判断数据类型,如果数据类型不符合,直接返回false;
然后判断是否为整数,或者其他的特殊情况
Number.isInteger(true); // false Number.isInteger(''); //false Number.isInteger(25.0); //true js中25.0===25 Number.isInteger(Number.MIN_VALUE*0.5); // true 当小于最小正数 Number.isInteger(1.0000000000000004); //false 小数点后16位 Number.isInteger(1.00000000000000004); // true 小数点后17位
5. Number.isSafeInteger(number)--判断整数是否在精度范围
先判断数据类型,后判断是否在精度范围内的整数,-2^53
到2^53
之间(不含两个端点)。
Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false // 有一点需要注意,对于运算符两侧的数值来说,每个值都要复合,才能得出正确的结果 Number.isSafeInteger(9007199254740993 - 990) // true 9007199254740993 - 990 // 返回结果 9007199254740002 // 正确答案应该是 9007199254740003
2. 实例方法
1.toString([N进制])--将数值转为N进制字符串
默认转为10进制,指定后转为指定的进制
(0x11).toString(); // "17" (0x11).toString(2); // "10001"
2. toFixed(number) --将数值转为固定小数位数的字符串
(10.005).toFixed(2); // "10.01"
3. toExponential(number)--转为科学计数法表示的字符串
number表示小数的个数
(10).toExponential(2); // "1.00e+1"
4. toPrecision(number)--转为固定有效数字的字符串
number表示所有有效数字的长度
(10).toPrecision(5); // "10.000"
3.Math对象
Math就是一个对象,不是构造函数。
1.静态属性--只读属性
1. Math.PI---𝛑
2.Math.LN2 ---以e为底,2的对数
3.Math.LN10---以e为底,10的对数
4.Math.LOG2E---以2为底,e的对数,等于1/Math.LN2
5.Math.LOG10E---以10为底,e的对数,等于1/Math.LN10
6.Math.E-------e的值
7.Math.SQRT1_2--0.5的平方根
8.Math.SQRT2----2的平方根
2.静态方法--数据处理方法
Math的方法会先将不是数值的参数,转化为数值。
这点和Number的静态方法不同。
1.Math.ceil(number)---向上取整
2.Math.floot(number)--向下取整
3.Math.trunc(number)--取整
4.Math.round(number)--四舍五入
// 注意正数和负数都向数据增大的方向 Math.round(0.5);// 1 Math.round(-0.5); //-0
5.Math.abs(number)---取绝对值
6.Math.random()-----取[0,1)的随机数
7.Math.max(多个数值)---取最大值
Math.max(1,25,6); // 25
8.Math.min(,,,)-------取最小值
9.Math.clz32(number) ---转32位无符号整数,返回二进制前导0个数
参数值是负数时返回0;
Math.clz32(1000) // 22 // 相当于 Math.clz32(0b1111101000), 1000相当于10个二进制数 Math.clz32(0b0010); // 30
10. Math.fround(number)---将64位双精度浮点数转为32位单精度浮点数形式
数值精度是24位,超过2**24的值失去精度
Math.fround(NaN) // NaN Math.fround(Infinity) // Infinity // 未丢失有效精度 Math.fround(1.125) // 1.125 // 丢失精度 Math.fround(0.3) // 0.30000001192092896
2. 静态方法--运算方法
1. Math.sqrt(number)----平方根
2.Math.cbrt(number)----立方根
3.Math.hypot(n1,n2...)----所有参数平方根和的平方根
Math.hypot(3,4); //5
4.Math.pow(x,y)--------x的y次方
5.Math.immu(x,y)------返回32位带符号数相乘的结果
Math.imul(-4,5); // -20 // 和普通的乘法运算不同的点在于超出精度范围的值相乘,会返回正确的底位数值
6.三角函数
Math.sin():返回参数的正弦(参数为弧度值)
Math.cos():返回参数的余弦(参数为弧度值)
Math.tan():返回参数的正切(参数为弧度值)
Math.asin():返回参数的反正弦(返回值为弧度值)
Math.acos():返回参数的反余弦(返回值为弧度值)
Math.atan():返回参数的反正切(返回值为弧度值
7.双曲函数方法
Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)
Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)
Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)
Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)
Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)
Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)
3. 静态方法---对数方法
1.Math.exp(n)---------e的n次方
2.Math.expm1(n)-------e的n次方-1; // minuse1 Math.exp(x)-1
3. Math.log(n)----返回以e为底的对数值
4.Math.log1p(n)---以e为底的对数+1 // 1plus Math.log(1+n)
5.Math.log10(n)----以10为底的对数
Math.log10(10); //1
6.Math.log2(n)----以2为底的对数
4. 静态方法---判断正负
Math.sign(number);
number > 0 ;返回1
number < 0; 返回-1
number === 0; 返回0;
NaN, 返回NaN
4.运算符
1.逻辑运算符
逻辑运算符组成的表达式,根据不同运算符,返回值不同
1.&&与运算符
1)如果运算符单独使用,第一个布尔值是false, 返回第一个的值;
false && 5; // false
否则,返回第二个的值(不管第二个是什么)!
4 && (<div>1</div>) // 相当于 if (4) { return (<div>1</div>) }
2)如果多个运算符连续使用,返回第一个是false的值,或者最后一个值
2. || 或运算符
1)如果单独使用,第一个算子布尔值是true,返回第一个的值;
否则返回第二个的值。
2)如果连续使用,返回第一个是true的值,或者最后一个值
ps: 常用于赋初值
var obj = obj || {a:1}
2. 逗号运算符
返回最后一个表达式的值
var x = (1,2,3,4); // x===4
3.三元运算符
三元运算符和赋值运算符都是右结合运算符
4.void运算符
void运算符是执行一个表达式(表达式本身一定会返回一个值),但是不返回任何值,或者返回undefined;
void的优先级特别高,要使用(), 否则容易出现错误。
void 1+3; //NaN // 因为会(void 1) + 3 --->undefined + 3 --->NaN void (1+3); //undefined
应用:可以用来阻止浏览器默认行为,相当于return false;
<a href="javascript: void(document.form.submit())">提交</a>
5. 位运算符
!!位运算符只能作用与32位带符号整数
如果是存储的64位浮点数,位运算符会自动舍弃小数部分。
1.位或 |
应用: 取整(不适合大于2**32-1的值)
8.9 | 0; // 8 -23.3 | 0; //-23 0.9 | 0 ;// 0
2. 位与 &
3.位反~
应用:
1)~用于一个值时,相当于先调用Number(), 再取反
2)一个数值取反的结果= -1-原始值
~3; //-1-3=== -4
ps:负数的二进制表示法是绝对值取反+1;
通过二进制推十进制,如果符号位是1, 则-1, 取反 ,加负号;
3)取整~~;和其他位运算取反相比也是最快
~~2.9; //2
特殊值取反
~NaN; // -1 ~[]; // -1 相当于~Number([])-->~0 ~0; // -1 ~null; // -1 相当于~Number(null)-->~0
4. 异或^
应用:
1) 互换变量的值最快的方法
var a=8, b=9; a^=b;b^=a;a^=b; // a===9, b===8
还可以通过[]解构互换变量
var a=8, b=9; var [a,b] = [b,a]; // a=== 9; b===8
2) 取整
8.9 ^ 0; //8
5. 左移运算符<<
符号位不动。
应用:
1)数值乘以2的倍数的时候
4 << 1; // 4*(2**1)-->8 -4 << 2; // -4*(2**2) -->-4*4-->-16
2) 取整
8.9 << 0; // 8
3) 将rgb格式转为hex
var color={r: 186, g: 218, b:85}; function rgb2hex(r,g,b) { // 1<<24是预防r是0的话,最后结果是4位,所以在前面加一个值 return '#' + ((1<<24) + (r << 16) + (g<<8) + b) .toString(16) .slice(1) // 将之前加的值去掉 } rgb2hex(color.r, color.g, color.b); //#bada55
6. 右移运算符(>>)
应用:
1)求除以2的倍数的商
4 >> 1; // 2 4/2的商 5 >> 2; // 1 5/(2**2) 的商
2) 取整
8.9 >> 0; // 8
7. 带符号位的右移运算符(>>>)
正数的话,功能和>>相同;
应用:
查看负数以二进制存储的形式值对应的十进制数
-1 >>> 0; // 4294967295 (1111....1111)--32个1