JS学习33:数值类型基础知识
2016-11-14 20:07
471 查看
1、概述
JavaScript 不是类型语言。与许多其他编程语言不同,JavaScript 不定义不同类型的数字,比如整数、短、长、浮点等等。JavaScript 中的所有数字都存储为根为 10 的 64 位(8 比特),浮点数。
所以在 JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。例如:
1 === 1.0 // true 1 + 1.0 // 2
所以在 javascript 中,精确的整数(不使用小数点或指数计数法)最多为 16 位数字;精确的浮点数(包含整数和小数部分,不包含小数点)的最大位数也是 16位数字,例如:
1234567890123456 // 1234567890123456(精确16位数字) 12345678901234567 // 12345678901234568(只精确16位数字,多余的数字可能不准确) 12345678901234560 // 12345678901234560(只精确16位数字,多余的数字可能不准确) 0.1234567890123456 // 0.1234567890123456(精确16位数字) 1.123456789012345 // 1.123456789012345(精确16位数字) 123.1234567890123 // 123.1234567890123(精确16位数字) 123.12345678901233 // 123.12345678901232(只精确16位数字,多余的数字可能不准确)
但是浮点运算并不总是 100% 准确,由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心,例:
0.1 + 0.2 === 0.3 // 0.1+0.2 = 0.30000000000000004 // false 0.3 / 0.1 // 2.9999999999999996
根据国际标准IEEE 754,64位浮点数格式的64个二进制位中,第0位到第51位储存有效数字部分,第52到第62位储存指数部分,第63位是符号位,0表示正数,1表示负数。
因此,JavaScript提供的有效数字的精度为53个二进制位(IEEE 754规定有效数字第一位默认为1,再加上后面的52位),也就是说,小于2的53次方的整数都可以精确表示。
Math.pow(2, 53) // 54个二进制位 // 9007199254740992 Math.pow(2, 53) + 1 // 9007199254740992 Math.pow(2, 53) + 2 // 9007199254740994 Math.pow(2, 53) + 3 // 9007199254740996 Math.pow(2, 53) + 4 // 9007199254740996
从上面示例可以看到,大于2的53次方以后,整数运算的结果开始出现错误。所以,大于等于2的53次方的数值,都无法保持精度。
Math.pow(2, 53) // 9007199254740992 9007199254740992111 // 9007199254740992000
上面示例表明,大于2的53次方以后,多出来的有效数字(最后三位的111变成了000)都会无法保存,变成0。
另一方面,64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。所以,JavaScript能够表示的数值范围为(-22048, 22048),超出这个范围的数无法表示。
2、表示及表示转换
数值可以字面形式直接表示,也可以采用科学计数法表示。以下两种情况,JavaScript会自动将数值转为科学计数法表示,其他情况都采用字面形式直接表示。小数点前的数字多于21位。
小数点后的零多于5个。
如:
1234567890123456789012 // 1.2345678901234568e+21 // (整数部分超过16位数字,多余的数字将不精确 // 整体超过21位数字,使用科学计数法表示) 123456789012345678901 // 123456789012345678901 // (整数部分超过16位数字,多余的数字将不精确 // 但整体尚未超过21位数字,使用字面形式直接表示) 0.0000001 // 1e-7 // (小数部分开头超过5个连续0,使用科学计数法表示) 0.0001002 // 0.0001002 // (小数部分开头没有超过5个连续0,使用字面形式直接表示)
数值表示转换:
// 转换为科学计数表示 (123).toExponential(1); // "1.2e+2" (123).toExponential(5); // "1.23000e+2"
3、进制及进制转换
任何数值其实都可以转换为任何进制,其中常用的进制有十进制、二进制、八进制、十六进制,其中二进制、八进制、十六进制是应计算机而生的,因为他们都是2的N次幂。在表示不同进制时:11 // 十进制 // 相当于十进制的11(1*10+1) 011 // 八进制 // 相当于十进制的9(1*8+1) 0x11 // 十六进制 // 相当于十进制的17(1*16+1)
进制转换:
// 1、十进制转换其他进制 // 十进制转换为二进制 (123).toString(2); // "1111011" // 十进制转换为八进制 (123).toString(8); // "173" // 十进制转换为十六进制 (123).toString(16); // "7b" // 2、八进制转换其他进制 // 八进制转换为二进制 (0123).toString(2); // "1010011" // 八进制转换为十进制 (0123).toString(10); // "83" // 八进制转换为十六进制 (0123).toString(16); // "53" // 3、十六进制转换其他进制 // 十六进制转换为二进制 (0x123).toString(2); // "100100011" // 八进制转换为八进制 (0x123).toString(8); // "443" // 八进制转换为十进制 (0x123).toString(10); // "291"
4、parseInt与parseFloat
parseInt是将数值或字符串解析为十进制数值的整数。
parseFloat是将数值或字符串解析为十进制浮点数。
parseInt语法为:
parseInt(string, radix); // string为待解析的字符串或数值 // radix表示待解析的字符串或数值的进制
parseInt有个误区,通常认为该方法是将字符串或数值转换为指定进制。比如:
// => 错误认为会将十进制的10转换为八进制的12 parseInt(10, 8);
parseInt没有转换进制的功能,它的字面意思是解析(parse)而不是转换(change),它只是将目标解析为十进制,所以:
// 返回的结果不是8,而是NaN // 因为八进制当中没有8这个数值 parseInt(8, 8);
parseInt的解析有以下特点:
A、会省略待解析的字符串的开头和结尾空格:
parseInt(' 1 '); // 1 parseInt('1'); // 1
B、只保留从开头(不包含正负号)开始的连续数字,并会省略连续数字开头的0(但0后面为x较为特殊,表示十六进制):
parseInt('2013年11月14日'); // 2013 parseInt('2013'); // 2013 parseInt('-99°C'); // -99 parseInt('-99'); // -99 parseInt('+99°C'); // 99 parseInt('+99'); // 99 parseInt('010-1234567'); // 10 parseInt('10-1234567'); // 10 parseInt('-010-1234567'); // 10 parseInt('-10-1234567'); // 10 parseInt('0a11'); // 0 parseInt('0x11'); // 17(并不是0)
C、进制解析,可以解析[2,32]之间进制的数值为十进制:
parseInt(011); // 9=1*8+1 parseInt("011"); // 11 parseInt(11,8); // 9=1*8+1 parseInt(0x11); // 17=1*16+1 parseInt("0x11"); // 17=parseInt(0x11) parseInt(11,16); // 17=1*16+1
parseInt的八进制和十六进制的字符串解析比较特殊,容易引起误会。
D、不符合以上规则的将解析为NaN:
parseInt('云淡然'); // NaN(开头没有数字) parseInt('云淡然2013'); // NaN(数字不在开头) parseInt('--1'); // NaN(正负号后面不是数字) parseInt(8, 8); // NaN(数字8不在八进制中)
parseFloat与parseInt的解析规则几乎一致,区别在于:
A、parseFloat支持小数
B、parseFloat符合概述和表示的规则
如:
parseFloat(1234567890123456); // 1234567890123456 parseFloat(12345678901234567); // 12345678901234568(不同,参考概述) parseFloat(123.1234567890123); // 123.1234567890123 parseFloat(123.12345678901233); // 123.12345678901232(不同,参考概述) parseFloat(123456789012345678901); // 123456789012345678901 parseFloat(1234567890123456789012); // 1.2345678901234568e+21(科学计数法,参考表示) parseFloat(0.0001002); // 0.0001002 parseFloat(0.0000002); // 2e-7(科学计数法,参考表示)
5、Number
Number是将数字或字符串类型转换为数值对象,必要时两者之间可以自动转换。var a=1; var b=Number(a); a.toFixed(2); // 1.00 b.toFixed(2); // 1.00 a(数字基本类型)和b(数字对象类型)都有了对象属性,a自动转换为数字对象类型
和parseInt以及parseFloat类似,Number方法会先将参数解析,然后转换为数值对象。
6、参考资料
http://javascript.ruanyifeng.com/grammar/number.htmlhttp://www.w3school.com.cn/js/js_obj_number.asp
http://www.w3school.com.cn/js/jsref_parseInt.asp
http://www.w3school.com.cn/js/jsref_parseFloat.asp
相关文章推荐
- js基础知识三(number类型的所有数值)
- 【Java学习笔记】基础知识学习1【基本输出,数据类型,基础运算符号】
- JS基础知识(基本类型 引用类型)
- JS中的事件类型和事件属性的基础知识
- Js_基础知识学习_01
- Node.js学习--基础知识(1)--入门
- js基础知识相关学习笔记记录
- JavaScript 入门基础知识 想学习js的朋友可以参考下
- swift 学习(一)基础知识 (基本数据类型,操作符,流控制,集合)
- Go语言基础知识总结(语法、变量、数值类型、表达式、控制结构等)
- Node.js学习--基础知识(5)--npm
- 根据w3cSchool学习javascript整理js的一些基础知识
- JavaScript 入门基础知识 想学习js的朋友可以参考下
- java学习02-java基础知识、基本数据类型、运算符
- 栋栋晓09:Javascript学习总结:基础知识1(语法、关键字和保留字、变量、数据类型、操作符)
- JavaScript学习笔记(一)——JS基础知识介绍
- js基础知识学习站点汇总
- Java基础知识学习二(数据类型及运算)
- Node.js学习--基础知识(2)--异步IO与事件式编程
- JS基础知识之:DOM学习