JS 数字类型只有number类型,number类型至关于其余强类型语言中的double类型(双精度浮点型
),不区分浮点型和整数型。javascript
number 有四种进制表示方法,十进制,二进制,八进制和十六进制java
表示方法es6
数字0和字母B或者小写字母b
) ,后接1或者0表示二进制数0o
,后接小于8的数字表示八进制0x
或者0X
开头,后接0-9数字和a-e五个英文字母parseInt
和 toString
编程
// toString转换,输入为Number,返回为String var n = 120; n.toString(); // "120" n.toString(2); // "1111000" n.toString(8); // "170" n.toString(16); // "78" n.toString(20); // "60" 0x11.toString(); // "17" 0b111.toString(); // "7" 0x11.toString(12);// "15" // parseInt转换,输入为String,返回为Number parseInt('110'); // 110 parseInt('110', 2); // 6 parseInt('110', 8); // 72 parseInt('110', 16); // 272 parseInt('110', 26); // 702 // toString和parseInt结合使用能够在两两进制之间转换 // 将 a 从36进制转为12进制 var a = 'ra'; // 36进制表示的数 parseInt(a, 36).toString(12); // "960"
因为Js的全部数字类型都是双精度浮点型(64位
)采用 IEEE754 标准数组
64位二进制数表示一个number数字
编程语言
其中 64位 = 1位符号位 + 11位指数位 + 52位小数位编码
符号位:用来表示数字的正负,-1^符号位数值,0为正数,1为负数es5
指数位:通常都用科学计数法表示数值大小,可是这里通常都是2进制的科学计数法,表示2的多少次方code
小数位:科学计数法前面的数值,IEEE745标准,默认全部的该数值都转为1.xxxxx这种格式,优势是能够省略一位小数位,能够存储更多的数字内容,缺点是丢失精度对象
大概能够理解为这张图
整数转二进制
好理解,除二取余法,7表示为 111 = 1x2^3 + 1x2^2 + 1x2^1
问题来了,小数转二进制!!
因为也须要转化为指数形式,例如 1/2 = 1 * 2^-1, 1/4 = 1 * 2^-2,因此小数的转化二进制过程是经过判断小数是否是满 1/2,1/4,8/1以此类推,换成数学公式就是 乘二取整法
0.1的二进制 0.1*2=0.2======取出整数部分0 0.2*2=0.4======取出整数部分0 0.4*2=0.8======取出整数部分0 0.8*2=1.6======取出整数部分1 0.6*2=1.2======取出整数部分1 0.2*2=0.4======取出整数部分0 0.4*2=0.8======取出整数部分0 0.8*2=1.6======取出整数部分1 0.6*2=1.2======取出整数部分1 接下来会无限循环 0.2*2=0.4======取出整数部分0 0.4*2=0.8======取出整数部分0 0.8*2=1.6======取出整数部分1 0.6*2=1.2======取出整数部分1 因此0.1转化成二进制是:0.0001 1001 1001 1001…(无限循环) 0.1 => 0.0001 1001 1001 1001…(无限循环) 同理0.2的二进制是0.0011 0011 0011 0011…(无限循环)
计算机中的数字都是以二进制存储的,二进制浮点数表示法并不能精确的表示相似0.1这样 的简单的数字
若是要计算 0.1 + 0.2 的结果,计算机会先把 0.1 和 0.2 分别转化成二进制,而后相加,最后再把相加获得的结果转为十进制
但有一些浮点数在转化为二进制时,会出现无限循环 。好比, 十进制的 0.1 转化为二进制,会获得以下结果:
0.1 => 0.0001 1001 1001 1001…(无限循环)
0.2 => 0.0011 0011 0011 0011…(无限循环)
而存储结构中的尾数部分最多只能表示 53 位。为了能表示 0.1,只能模仿十进制进行四舍五入了,但二进制只有 0 和 1 , 因而变为 0 舍 1 入 。 所以,0.1 在计算机里的二进制表示形式以下:
0.1 => 0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 101
0.2 => 0.0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 001
用标准计数法表示以下:
0.1 => (−1)0 × 2^4 × (1.1001100110011001100110011001100110011001100110011010)2
0.2 => (−1)0 × 2^3 × (1.1001100110011001100110011001100110011001100110011010)2
在计算浮点数相加时,须要先进行 “对位”,将较小的指数化为较大的指数,并将小数部分相应右移:
最终,“0.1 + 0.2” 在计算机里的计算过程以下:
通过上面的计算过程,0.1 + 0.2 获得的结果也能够表示为:
(−1)0 × 2−2 × (1.0011001100110011001100110011001100110011001100110100)2=>.0.30000000000000004
经过 JS 将这个二进制结果转化为十进制表示:
(-1)0 * 2-2 * (0b10011001100110011001100110011001100110011001100110100 * 2**-52); //0.30000000000000004
console.log(0.1 + 0.2) ; // 0.30000000000000004
这是一个典型的精度丢失案例,从上面的计算过程能够看出,0.1 和 0.2 在转换为二进制时就发生了一次精度丢失,而对于计算后的二进制又有一次精度丢失 。所以,获得的结果是不许确的。
原生方法类
console.log((0.1 + 0.2).toFixed(12) == 0.3) > true console.log((0.1 + 0.2).toFixed(12)) > 0.300000000000 console.log((2.4/0.8).toFixed(12)) > 3.000000000000
parseFloat((a+b).toFixed(2))
第三方封装类库
math库
//统一配置math.js math.config({ number: 'BigNumber', // 'number' (default), precision: 20 }); // 转换数字类型 var temp = math.bignumber(a) * math.bignumber(b) // 提取数字类型,否则会是一个math对象 var result = math.number(temp)
bignumber,big,decimal等