JS魔法堂:再识Number type
Brief
本来只打算理解JS中0.1 + 0.2 == 0.30000000000000004的原因,但发现自己对计算机的数字表示和运算十分陌生,于是只好恶补一下。以下是恶补后的成果:
理解JS Number type背后的IEEE 754 64位双精度数值编码后,0.1 + 0.2 == 0.30000000000000004就不言而喻了,但单纯的理解了现象的本质是不够,我们需要的是如何解决这类问题,不然下次遇到同类问题我们只能同样的无力而已:(
但在寻求或自己手写工具库前,我觉得还是先了解JS为我们提供的原生API比较明智。
APIs
Numeric literal
ES5 APIs
OctalLiteral,八进制数值字面量,数值域以0开始且不含小数点。如:012转换为十进制数值为10 。
注意:在strict mode中OctalLiteral是非法的。
DecimalLiteral,十进制数值字面量,数值域以1-9或.或0.开始。
还有含指数和不含指数两种字面量形式
含指数形式:1.1e2表示110
e或E表示指数提示符,后面紧跟则指数值Exp;
Exp必须为正/负整数或零;
基数固定为10 。
HexLiteral,十六进制数值字面量,数值域以0x或0X开始。如:0x0F转换为十进制数值为15 。
ES6 APIs
BinaryLiteral, 二进制数值字面量,数值域以0b或0B开始。如:0b0100转换为十进制数值为4 。
OctalLiteral,八进制数值字面量,数值域以0o或0O开始。如:0o12转换为十进制数值为10 。
Number Function
当以Number([value])的方式调用时,返回值为Number value。
Number Constructor
当以new Number([value])的方式调用时,返回值为Number object。
Function Properties
ES5 APIs
Number.MIN_VALUE,可表示的最接近0的值。(2^53-1)*2^-1074 即约等于1.7976931348623157 × 10^308。
Number.MAX_VALUE,可表示的最大值。 (2^53-1)*2^971即约等于5 × 10^−324。
Number.NaN,返回Number type的Not-a-Number值。
Number.NEGATIVE_INFINITY,返回-Infinity。
Number.POSITIVE_INFINITY,返回Infinity。
window.isFinite([value]),判断value值是否为有限数。会先将value转换为Number value后再判断。
window.isNaN([value]),判断value值是否为Not-a-Number。会先将value转换为Number value后再判断。
window.parseInt([value], [radix=10]),以radix作为进制将value转换为十进制整数。
window.parseFloat([value]),将value转换为实数。
ES6 APIs
Number.MIN_SAFE_INTEGER,可精确表示的整数范围下限。-Math.pow(2, 53)+1,即是-9007199254740991。
Number.MAX_SAFE_INTEGER,可精确表示的整数范围上限。Math.pow(2, 53)-1,即是9007199254740991。
Number.EPSILON,极小值(2.220446049250313e-16),作为允许的误差范围使用。
(当某运算结果的误差小于Number.EPSILON则认为该结果是可被接受的)
判断是否可接受的函数:
function withinErrorMargin (left, right) {
return Math.abs(left - right) < Number.EPSILON
}
Number.isFinite([value]),判断value值是否为有限数。若value不为Number type则直接返回false。
Number.isNaN([value]),判断value值是否为Not-a-Number。若value不为Number type则直接返回false。
Number.parseInt([value], [radix=10]),以radix作为进制将value转换为十进制整数。
Number.parseFloat([value]),将value转换为实数。
Number.isInteger([value]),value为number类型,且小数部分全为0则返回true。(Number.isInteger(2.0)返回true)
Number.isSaveInteger([value]),value为number类型,且Number.MIN_SAFE_INTEGER <= value <= Number.MAX_SAFE_INTEGER则返回true。
Number.prototype Properties
ES5 APIs
Number.prototype.toString([radix=10]):DOMString,返回以radix作为进制输出数值字符串,radix为2~36。
注意:对于负数而言,当radix为2时返回的是不补码编码的位模式,而是形如 -10100.0101011 的 "负号" + "原码位模式" 的形式。
Number.prototype.valueOf():Number value,返回Number object的[[PrimitiveValue]]值。
Number.prototype.toFixed([fractionDigits=0]):DOMString,返回指定小数位的十进制定点数字符串。
注意:1.fractionDigits必须大于等于0和小于等于20,否则会抛RangeError;
2.若数值大于e21则直接返回Number.prototype.toString()的值;
3.若数值小于e21,则通过公式计算,所以和toString()的返回值不一定相同(两者均不精准)
(1000000000000000128).toString() === "1000000000000000100"
(1000000000000000128).toFixed(0) === "1000000000000000128"
(1000000000000000100).toString() === "1000000000000000100"
(1000000000000000100).toFixed(0) === "1000000000000000128"
Number.prototype.toPrecision([precision]):DOMString,返回指定精度的是十进制字数字符串。
注意:精度过高或过低都会引发数值的不精准。
(100.1).toPrecision(1) === "1e+2"
(100.1).toPrecision(17) === "100.09999999999999"
Number.prototype.toExponential(fractionDigits):DOMString,返回指定精度的是十进制字数科学计数法字符串
注意:精度过高或过低都会引发数值的不精准。
(100.1).toExponential(1) === "1.001e+2"
(100.1).toPrecision(16) === "1.0009999999999999e+2"
Consolusion
尊重原创,转载请注明
Thanks
http://es6.ruanyifeng.com/#docs/number
http://es5.github.io/#x15.7.4.5
- 算法之逆序对
- Windows平台分布式架构实践 - 负载均衡
- Web Service初探
- async & await 的前世今生(Updated)
- MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN
- Spring @Transactional踩坑记
- jvm运行时环境属性一览
- bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序
- C#集合类型大盘点
- 将spring源码导入到eclipse中
- 将struts源码导入eclipse
- 初探领域驱动设计(1)为复杂业务而生
- 最大公约数的算法
- 是时候开始用C#快速开发移动应用了
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- mybatis-plus代码生成器
- mybatis-plus逻辑删除
- mybatis-plus一些关键配置
- mybatis-plus自定义sql注入器
- k8s代码走读---kube-controller-manager
- 我们一起学一学渗透测试——黑客应该掌握的HTML基础知识(一)
- 一套漏洞组合拳接管你的账号
- 我们一起学一学渗透测试——黑客应该掌握的HTML基础知识(二)
- 我用Paddle Lite在树莓派3b+上从零开始搭建“实时表情识别”项目
- mybatis-plus:自动填充功能
- 词义类比与全局词共现信息不可兼得?基于飞桨实现的GloVe说可以
- MyBatis-plus乐观锁插件
- Jmeter(十九) - 从入门到精通 - JMeter监听器 -上篇(详解教程)
- python---rsa加密根据指数和模生成加密参数模板
- 搞了这么多年终于知道接口和抽象类的应用场景了