在控制台输入0.1+0.2,会得出以下结果

即不等于0.3。下面我们说一下原因。

一、存储原理

1.在计算机中数字无论是定点数还是浮点数都是以多位二进制的方式进行存储的。
2.在JS中数字采用的IEEE 754的双精度标准进行存储(存储一个数值所使用的二进制位数比较多,精度更准确)。

二、示例

在定点数中,如果我们以8位二进制来存储数字。
对于整数来说,十进制的35会被存储为: 00100011 其代表 2^5 + 2^1 + 2^0。
对于纯小数来说,十进制的0.375会被存储为: 0.011 其代表 1/2^2 + 1/2^3 = 1/4 + 1/8 = 0.375
对于像0.1这样的数值用二进制表示你就会发现无法整除,最后算下来会是 0.000110011…由于存储空间有限,最后计算机会舍弃后面的数值,所以我们最后就只能得到一个近似值
JS中采用的IEEE 754的双精度标准也是一样的道理在存储空间有限的情况下,当出现这种无法整除的小数的时候就会取一个近似值,在js中如果这个近似值足够近似,那么js就会认为他就是那个值。

console.log(0.1000000000000001)
// 0.1000000000000001 (中间14个0,会打印出本身)
console.log(0.10000000000000001)
// 0.1 (中间15个0,js会认为两个值足够近似,所以输出0.1)

由于0.1转换成二进制时是无限循环的,所以在计算机中0.1只能存储成一个近似值。
另外说一句,除了那些能表示成 x/2^n 的数可以被精确表示以外,其余小数都是以近似值得方式存在的。
在0.1 + 0.2这个式子中,0.1和0.2都是近似表示的,在他们相加的时候,两个近似值进行了计算,导致最后得到的值是0.30000000000000004,此时对于JS来说,其不够近似于0.3,于是就出现了0.1 + 0.2 != 0.3 这个现象。当然,也并非所有的近似值相加都得不到正确的结果。

三、解决方法

方式一: 想办法规避掉这类小数计算时的精度问题就好了,那么最常用的方法就是将浮点数转化成整数计算。因为整数都是可以精确表示的。

0.1+0.2 => (0.1*+0.2*)/

方式二 : js的Number对象有一个保留小数位数的方法:toFixed();传入一个需要保留的位数就OK:

(0.1+0.2).toFixed()==0.3

注:JS的小数点精确到第16位。

JS中0.1+0.2!=0.3的更多相关文章

  1. 在js中做数字字符串加0补位,效率分析

    分类: Jquery/YUI/ExtJs 2010-08-30 11:27 2700人阅读 评论(0) 收藏 举报 functiondate算法语言c 通常遇到的一个问题是日期的“1976-02-03 ...

  2. 在js中做数字字符串补0

    转自(http://blog.csdn.net/aimingoo/article/details/4492592) 通常遇到的一个问题是日期的“1976-02-03 HH:mm:ss”这种格式 ,我的 ...

  3. js中setTimeout() 时间参数为0

    当看到下面 这种setTimeout 设置为0 写法的时候一脸懵逼,完全没用过. var fuc = [1,2,3]; for(var i in fuc){ setTimeout(function() ...

  4. java、js中实现无限层级的树形结构(类似递归)

    js中: var zNodes=[ {id:0,pId:-1,name:"Aaaa"}, {id:1,pId:0,name:"A"}, {id:11,pId:1 ...

  5. js中要声明变量吗?

    你好,js语言是弱类型语言,无需申明即可直接使用,默认是作为全局变量使用的.建议:在function里时应使用var 申明变量,这样改变量仅仅只在function的生存周期内存在,不会污染到,全局控件 ...

  6. 在JS中关于堆与栈的认识function abc(a){ a=100; } function abc2(arr){ arr[0]=0; }

    平常我们的印象中堆与栈就是两种数据结构,栈就是先进后出:堆就是先进先出.下面我就常见的例子做分析: main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main( ...

  7. 字符串0.在php和js中转换为布尔类型 值是false还是true

    在php 中 $a = '0'; $b = (bool)$a; var_dump($a);//输出false 在js中官方说明: Note:If the value parameter is omit ...

  8. js中的0就是false,非0就是true及案例

    在处理js代码判断真假时经常会这么写. 但fun()可能得到的是数字0,这可不是表示的没有值,但是!js中的数字0就是false,非0就是true. 于是0就被无情的当做false了. 已经被这个坑过 ...

  9. 深入理解 Node.js 中 EventEmitter源码分析(3.0.0版本)

    events模块对外提供了一个 EventEmitter 对象,即:events.EventEmitter. EventEmitter 是NodeJS的核心模块events中的类,用于对NodeJS中 ...

  10. 为什么js中要用void 0 代替undefined

    这个是Backbone.js中的一句源码 if (callback !== void 0 && 'context' in opts && opts.context == ...

随机推荐

  1. python基础[1]——python运算符&python数据类型之数值型

    python常用运算符&数字&布尔值 上节回顾 一.变量名和标识符 变量名的命名规范 (1)只能包含数字,字母和下划线 (2)只能以字母和下划线开头(不能以数字开头) (3)标识符是区 ...

  2. 使用nutz框架,找不到入口函数,访问Url报404

    案例 今天在跟着nutz框架教程去配置demo时,发现访问URL找不到入口函数,出现了Search mapping for path=/user/count : NOT Action match 异常 ...

  3. 线程池之 ThreadPoolExecutor

    线程池之 ThreadPoolExecutor + 面试题 线程池介绍 线程池(Thread Pool):把一个或多个线程通过统一的方式进行调度和重复使用的技术,避免了因为线程过多而带来使用上的开销. ...

  4. 量子搜索算法 Grover search

    问题定义: Problem: \(f: \{ 0,1,2,3,--,N-1 \} \rightarrow \{0,1\}\) 找到 \(f(x)=1\) 的x 解法 经典解法: 经典解法很简单,就是把 ...

  5. 20190708三人开黑CF模拟赛

    7月8号晚上8点和两位巨佬开了一场虚拟cf: [Helvetic Coding Contest 2018 online mirror (teams allowed, unrated)] 我这么蔡,只A ...

  6. nginx 源码编译 用OPENSSL源码 开启 SSL

    ./configure --prefix=/usr/local/nginx --with-openssl=/home/uniqs/thirdparty/openssl/openssl-1.1.1d - ...

  7. Java 接口及接口回调_Chris

    题目: 利用接口和接口回调,实现简单工厂模式,当输入不同的字符,代表相应图形时,利用工厂类获得图形对象,再计算以该图形为底的柱体体积. 代码: 1.Test.java /** * 测试类,包含一个主方 ...

  8. java字符编码-Unicode编码问题刨根究底

    博客搬家: java字符编码问题 前段时间在读<java核心技术卷一>,遇到一些名词:码点.代码单元等,其实字面意思不难理解,解释如下 码点(code point):Unicode编码表中 ...

  9. [terminal]关于进度条的学习

    在PowerShell中隐藏光标 在pip的源码C:\Python36\Lib\site-packages\pip\utils\ui.py中发现了: @contextlib.contextmanage ...

  10. sql中常量和变量的引用

    String name =jtf.getText().trim(); String sql="select * from stu where stuname='  "+name+& ...